Merge "pkg/index: check for deletions in EdgesTo"

This commit is contained in:
Brad Fitzpatrick 2013-11-28 18:46:07 +00:00 committed by Gerrit Code Review
commit 3db0eca58c
3 changed files with 80 additions and 27 deletions

View File

@ -952,43 +952,61 @@ func (x *Index) GetImageInfo(fileRef blob.Ref) (camtypes.ImageInfo, error) {
func (x *Index) EdgesTo(ref blob.Ref, opts *camtypes.EdgesToOpts) (edges []*camtypes.Edge, err error) {
it := x.queryPrefix(keyEdgeBackward, ref)
defer closeIterator(it, &err)
permanodeParents := map[string]blob.Ref{} // blobref key => blobref set
permanodeParents := make(map[string]*camtypes.Edge)
for it.Next() {
keyPart := strings.Split(it.Key(), "|")[1:]
if len(keyPart) < 2 {
continue
}
parent := keyPart[1]
parentRef, ok := blob.Parse(parent)
edge, ok := kvEdgeBackward(it.Key(), it.Value())
if !ok {
continue
}
valPart := strings.Split(it.Value(), "|")
if len(valPart) < 2 {
if x.IsDeleted(edge.From) {
continue
}
parentType, parentName := valPart[0], valPart[1]
if parentType == "permanode" {
permanodeParents[parent] = parentRef
if x.IsDeleted(edge.BlobRef) {
continue
}
edge.To = ref
if edge.FromType == "permanode" {
permanodeParents[edge.From.String()] = edge
} else {
edges = append(edges, &camtypes.Edge{
From: parentRef,
FromType: parentType,
FromTitle: parentName,
To: ref,
})
edges = append(edges, edge)
}
}
for _, parentRef := range permanodeParents {
edges = append(edges, &camtypes.Edge{
From: parentRef,
FromType: "permanode",
To: ref,
})
for _, e := range permanodeParents {
edges = append(edges, e)
}
return edges, nil
}
func kvEdgeBackward(k, v string) (edge *camtypes.Edge, ok bool) {
// TODO(bradfitz): garbage
keyPart := strings.Split(k, "|")
valPart := strings.Split(v, "|")
if len(keyPart) != 4 || len(valPart) != 2 {
// TODO(mpl): use glog
log.Printf("bogus keyEdgeBackward index entry: %q = %q", k, v)
return
}
if keyPart[0] != "edgeback" {
return
}
parentRef, ok := blob.Parse(keyPart[2])
if !ok {
log.Printf("bogus parent in keyEdgeBackward index entry: %q", keyPart[2])
return
}
blobRef, ok := blob.Parse(keyPart[3])
if !ok {
log.Printf("bogus blobref in keyEdgeBackward index entry: %q", keyPart[3])
return
}
return &camtypes.Edge{
From: parentRef,
FromType: valPart[0],
FromTitle: valPart[1],
BlobRef: blobRef,
}, true
}
// GetDirMembers sends on dest the children of the static directory dir.
func (x *Index) GetDirMembers(dir blob.Ref, dest chan<- blob.Ref, limit int) (err error) {
defer close(dest)

View File

@ -825,16 +825,15 @@ func EdgesTo(t *testing.T, initIdx func() *index.Index) {
idx := initIdx()
id := NewIndexDeps(idx)
id.Fataler = t
defer id.DumpIndex(t)
// pn1 ---member---> pn2
pn1 := id.NewPermanode()
pn2 := id.NewPermanode()
id.AddAttribute(pn1, "camliMember", pn2.String())
claim1 := id.AddAttribute(pn1, "camliMember", pn2.String())
t.Logf("edge %s --> %s", pn1, pn2)
id.DumpIndex(t)
// Look for pn1
{
edges, err := idx.EdgesTo(pn2, nil)
@ -853,6 +852,41 @@ func EdgesTo(t *testing.T, initIdx func() *index.Index) {
t.Errorf("Wrong edge.\n GOT: %v\nWANT: %v", got, want)
}
}
// Delete claim -> break edge relationship.
del1 := id.Delete(claim1)
t.Logf("del claim %q deletes claim %q, breaks link between p1 and p2", del1, claim1)
// test that we can't find anymore pn1 from pn2
{
edges, err := idx.EdgesTo(pn2, nil)
if err != nil {
t.Fatal(err)
}
if len(edges) != 0 {
t.Fatalf("num edges = %d; want 0", len(edges))
}
}
// Undelete, should restore the link.
del2 := id.Delete(del1)
t.Logf("del claim %q deletes del claim %q, restores link between p1 and p2", del2, del1)
{
edges, err := idx.EdgesTo(pn2, nil)
if err != nil {
t.Fatal(err)
}
if len(edges) != 1 {
t.Fatalf("num edges = %d; want 1", len(edges))
}
wantEdge := &camtypes.Edge{
From: pn1,
To: pn2,
FromType: "permanode",
}
if got, want := edges[0].String(), wantEdge.String(); got != want {
t.Errorf("Wrong edge.\n GOT: %v\nWANT: %v", got, want)
}
}
}
func Delete(t *testing.T, initIdx func() *index.Index) {

View File

@ -157,6 +157,7 @@ type Edge struct {
FromType string // "permanode", "directory", etc
FromTitle string // name of source permanode or directory
To blob.Ref
BlobRef blob.Ref // the blob responsible for the edge relationship
}
func (e *Edge) String() string {