Add 'edgeback' key to index, for going backwards.

Change-Id: I43057a6fb96c3e8d9364002288d5c7b9ad2fd034
This commit is contained in:
Brad Fitzpatrick 2012-11-03 14:25:48 +01:00
parent 7cde834f2a
commit 1466c77198
4 changed files with 68 additions and 3 deletions

View File

@ -18,7 +18,6 @@ package indextest
import (
"fmt"
"log"
"os"
"path/filepath"
"reflect"
@ -110,6 +109,12 @@ func (id *IndexDeps) SetAttribute(permaNode *blobref.BlobRef, attr, value string
return id.uploadAndSignMap(m)
}
func (id *IndexDeps) AddAttribute(permaNode *blobref.BlobRef, attr, value string) *blobref.BlobRef {
m := schema.NewAddAttributeClaim(permaNode, attr, value)
m["claimDate"] = id.advanceTime()
return id.uploadAndSignMap(m)
}
func (id *IndexDeps) UploadFile(fileName string, contents string) (fileRef, wholeRef *blobref.BlobRef) {
cb := &test.Blob{Contents: contents}
id.BlobSource.AddBlob(cb)
@ -130,7 +135,6 @@ func (id *IndexDeps) UploadFile(fileName string, contents string) (fileRef, whol
panic(err)
}
fb := &test.Blob{Contents: fjson}
log.Printf("Blob is: %s", fjson)
id.BlobSource.AddBlob(fb)
fileRef = fb.BlobRef()
_, err = id.Index.ReceiveBlob(fileRef, fb.Reader())
@ -212,6 +216,12 @@ func Index(t *testing.T, initIdx func() *index.Index) {
rootClaimTime := id.lastTime()
t.Logf("set attribute %q", rootClaim)
pnChild := id.NewPermanode()
memberRef := id.AddAttribute(pn, "camliMember", pnChild.String())
t.Logf("add-attribute claim %q points to member permanode %q", memberRef, pnChild)
memberRefTime := id.lastTime()
lastPermanodeMutation := id.lastTime()
id.dumpIndex(t)
key := "signerkeyid:sha1-ad87ca5c78bd0ce1195c46f7c98e6025abbaf007"
@ -240,6 +250,11 @@ func Index(t *testing.T, initIdx func() *index.Index) {
t.Fatalf("%q = %q, want %q (permanode)", key, g, e)
}
key = fmt.Sprintf("edgeback|%s|%s|%s", pnChild, pn, memberRef)
if g, e := id.Get(key), "permanode|"; g != e {
t.Fatalf("edgeback row %q = %q, want %q", key, g, e)
}
// PermanodeOfSignerAttrValue
{
gotPN, err := id.Index.PermanodeOfSignerAttrValue(id.SignerBlobRef, "camliRoot", "rootval")
@ -270,7 +285,7 @@ func Index(t *testing.T, initIdx func() *index.Index) {
&search.Result{
BlobRef: pn,
Signer: id.SignerBlobRef,
LastModTime: 1322443959,
LastModTime: lastPermanodeMutation.Unix(),
},
}
if !reflect.DeepEqual(got, want) {
@ -332,6 +347,15 @@ func Index(t *testing.T, initIdx func() *index.Index) {
Attr: "camliRoot",
Value: "rootval",
},
&search.Claim{
BlobRef: memberRef,
Permanode: pn,
Signer: id.SignerBlobRef,
Date: memberRefTime.UTC(),
Type: "add-attribute",
Attr: "camliMember",
Value: pnChild.String(),
},
})
if !reflect.DeepEqual(claims, want) {
t.Errorf("GetOwnerClaims results differ.\n got: %v\nwant: %v",

View File

@ -196,4 +196,24 @@ var (
},
nil,
}
// Given a blobref (permanode or static file or directory), provide a mapping
// to potential parents (they may no longer be parents, in the case of permanodes).
// In the case of permanodes, camliMember or camliContent constitutes a forward
// edge. In the case of static directories, the forward path is dir->static set->file,
// and that's what's indexed here, inverted.
keyEdgeBackward = &keyType{
"edgeback",
[]part{
{"child", typeBlobRef}, // the thing we want to find parent(s) of
{"parent", typeBlobRef}, // the parent (e.g. permanode blobref)
// the blobref is the blob establishing the relationship
// (for a permanode: the claim; for static: often same as parent)
{"blobref", typeBlobRef},
},
[]part{
{"parenttype", typeStr}, // either "permanode" or the camliType ("file", "static-set", etc)
{"name", typeStr}, // the name, if static.
},
}
)

View File

@ -197,6 +197,15 @@ func (ix *Index) populateClaim(br *blobref.BlobRef, ss *schema.Superset, sniffer
key := keySignerAttrValue.Key(verifiedKeyId, ss.Attribute, ss.Value, ss.ClaimDate, br)
bm.Set(key, keySignerAttrValue.Val(pnbr))
}
if search.IsBlobReferenceAttribute(ss.Attribute) {
targetRef := blobref.Parse(ss.Value)
if targetRef != nil {
key := keyEdgeBackward.Key(targetRef, pnbr, br)
bm.Set(key, keyEdgeBackward.Val("permanode", ""))
}
}
return nil
}

View File

@ -210,6 +210,18 @@ func IsIndexedAttribute(attr string) bool {
return false
}
// IsBlobReferenceAttribute returns whether attr is an attribute whose
// value is a blob reference (e.g. camliMember) and thus something the
// indexers should keep inverted indexes on for parent/child-type
// relationships.
func IsBlobReferenceAttribute(attr string) bool {
switch attr {
case "camliMember":
return true
}
return false
}
func IsFulltextAttribute(attr string) bool {
switch attr {
case "tag", "title":