mirror of https://github.com/perkeep/perkeep.git
index: cleanup and formalizing key formats into their own types
Change-Id: I36aaa74ee7a4349bb00c1ac06285d4c43f4c61bc
This commit is contained in:
parent
f23aadf801
commit
dd5726a4d1
|
@ -127,6 +127,30 @@ func New(s IndexStorage) *Index {
|
|||
}
|
||||
}
|
||||
|
||||
type prefixIter struct {
|
||||
Iterator
|
||||
prefix string
|
||||
}
|
||||
|
||||
func (p *prefixIter) Next() bool {
|
||||
v := p.Iterator.Next()
|
||||
if v && !strings.HasPrefix(p.Key(), p.prefix) {
|
||||
return false
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (x *Index) queryPrefix(key *keyType, args ...interface{}) *prefixIter {
|
||||
return x.queryPrefixString(key.Prefix(args...))
|
||||
}
|
||||
|
||||
func (x *Index) queryPrefixString(prefix string) *prefixIter {
|
||||
return &prefixIter{
|
||||
prefix: prefix,
|
||||
Iterator: x.s.Find(prefix),
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Index) GetRecentPermanodes(dest chan *search.Result, owner *blobref.BlobRef, limit int) os.Error {
|
||||
defer close(dest)
|
||||
// TODO(bradfitz): this will need to be a context wrapper too, like storage
|
||||
|
@ -141,13 +165,10 @@ func (x *Index) GetRecentPermanodes(dest chan *search.Result, owner *blobref.Blo
|
|||
|
||||
sent := 0
|
||||
var seenPermanode dupSkipper
|
||||
prefix := pipes("recpn", keyId, "")
|
||||
it := x.s.Find(prefix)
|
||||
|
||||
it := x.queryPrefix(keyRecentPermanode, keyId)
|
||||
defer it.Close()
|
||||
for it.Next() {
|
||||
if !strings.HasPrefix(it.Key(), prefix) {
|
||||
break
|
||||
}
|
||||
permaStr := it.Value()
|
||||
parts := strings.SplitN(it.Key(), "|", 4)
|
||||
if len(parts) != 4 {
|
||||
|
@ -191,12 +212,9 @@ func (x *Index) GetOwnerClaims(permaNode, owner *blobref.BlobRef) (cl search.Cla
|
|||
return nil, err
|
||||
}
|
||||
prefix := pipes("claim", permaNode, keyId, "")
|
||||
it := x.s.Find(prefix)
|
||||
it := x.queryPrefixString(prefix)
|
||||
defer it.Close()
|
||||
for it.Next() {
|
||||
if !strings.HasPrefix(it.Key(), prefix) {
|
||||
break
|
||||
}
|
||||
keyPart := strings.Split(it.Key(), "|")
|
||||
valPart := strings.Split(it.Value(), "|")
|
||||
if len(keyPart) < 5 || len(valPart) < 3 {
|
||||
|
@ -257,13 +275,10 @@ func (x *Index) PermanodeOfSignerAttrValue(signer *blobref.BlobRef, attr, val st
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
prefix := pipes("signerattrvalue", keyId, urle(attr), urle(val), "")
|
||||
it := x.s.Find(prefix)
|
||||
it := x.queryPrefixString(pipes("signerattrvalue", keyId, urle(attr), urle(val), ""))
|
||||
defer it.Close()
|
||||
if it.Next() {
|
||||
if strings.HasPrefix(it.Key(), prefix) {
|
||||
return blobref.Parse(it.Value()), nil
|
||||
}
|
||||
return blobref.Parse(it.Value()), nil
|
||||
}
|
||||
return nil, os.ENOENT
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package index
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type keyType struct {
|
||||
name string
|
||||
parts []keyPart
|
||||
}
|
||||
|
||||
func (k *keyType) Prefix(args ...interface{}) string {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(k.name)
|
||||
for _, arg := range args {
|
||||
buf.WriteString("|")
|
||||
// TODO(bradfitz): verify the type matches
|
||||
if s, ok := arg.(string); ok {
|
||||
buf.WriteString(s)
|
||||
} else {
|
||||
buf.WriteString(arg.(fmt.Stringer).String())
|
||||
}
|
||||
}
|
||||
buf.WriteString("|")
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
type keyPart struct {
|
||||
name string
|
||||
typ partType
|
||||
}
|
||||
|
||||
type partType int
|
||||
|
||||
const (
|
||||
typeKeyId partType = iota // PGP key id
|
||||
typeTime
|
||||
typeReverseTime // time prepended with "rt" + each numeric digit reversed from '9'
|
||||
typeBlobRef
|
||||
)
|
||||
|
||||
var (
|
||||
keyRecentPermanode = &keyType{
|
||||
"recpn",
|
||||
[]keyPart{
|
||||
{"owner", typeKeyId},
|
||||
{"modtime", typeReverseTime},
|
||||
{"claim", typeBlobRef},
|
||||
},
|
||||
}
|
||||
)
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package index
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestKeyPrefix(t *testing.T) {
|
||||
if g, e := keyRecentPermanode.Prefix("ABC"), "recpn|ABC|"; g != e {
|
||||
t.Errorf("recpn = %q; want %q", g, e)
|
||||
}
|
||||
}
|
|
@ -121,6 +121,7 @@ func (ix *Index) populateClaim(br *blobref.BlobRef, ss *schema.Superset, sniffer
|
|||
|
||||
bm.Set("signerkeyid:"+vr.CamliSigner.String(), verifiedKeyId)
|
||||
|
||||
// TODO(bradfitz): use keyRecentPermanode here instead of pipes() with "recpn".
|
||||
recentKey := pipes("recpn", verifiedKeyId, reverseTimeString(ss.ClaimDate), br)
|
||||
bm.Set(recentKey, pnbr.String())
|
||||
|
||||
|
|
Loading…
Reference in New Issue