mirror of https://github.com/perkeep/perkeep.git
pkg/index: check for deletions in EdgesTo
Also introduced and used kvEdgeBackward http://camlistore.org/issue/191 Change-Id: Ifdca9f2453ec0c7db55afc40cf0b5f1441b83158
This commit is contained in:
parent
2095a2c913
commit
fa32346860
|
@ -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) {
|
func (x *Index) EdgesTo(ref blob.Ref, opts *camtypes.EdgesToOpts) (edges []*camtypes.Edge, err error) {
|
||||||
it := x.queryPrefix(keyEdgeBackward, ref)
|
it := x.queryPrefix(keyEdgeBackward, ref)
|
||||||
defer closeIterator(it, &err)
|
defer closeIterator(it, &err)
|
||||||
permanodeParents := map[string]blob.Ref{} // blobref key => blobref set
|
permanodeParents := make(map[string]*camtypes.Edge)
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
keyPart := strings.Split(it.Key(), "|")[1:]
|
edge, ok := kvEdgeBackward(it.Key(), it.Value())
|
||||||
if len(keyPart) < 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
parent := keyPart[1]
|
|
||||||
parentRef, ok := blob.Parse(parent)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
valPart := strings.Split(it.Value(), "|")
|
if x.IsDeleted(edge.From) {
|
||||||
if len(valPart) < 2 {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
parentType, parentName := valPart[0], valPart[1]
|
if x.IsDeleted(edge.BlobRef) {
|
||||||
if parentType == "permanode" {
|
continue
|
||||||
permanodeParents[parent] = parentRef
|
}
|
||||||
|
edge.To = ref
|
||||||
|
if edge.FromType == "permanode" {
|
||||||
|
permanodeParents[edge.From.String()] = edge
|
||||||
} else {
|
} else {
|
||||||
edges = append(edges, &camtypes.Edge{
|
edges = append(edges, edge)
|
||||||
From: parentRef,
|
|
||||||
FromType: parentType,
|
|
||||||
FromTitle: parentName,
|
|
||||||
To: ref,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, parentRef := range permanodeParents {
|
for _, e := range permanodeParents {
|
||||||
edges = append(edges, &camtypes.Edge{
|
edges = append(edges, e)
|
||||||
From: parentRef,
|
|
||||||
FromType: "permanode",
|
|
||||||
To: ref,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return edges, nil
|
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.
|
// 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) {
|
func (x *Index) GetDirMembers(dir blob.Ref, dest chan<- blob.Ref, limit int) (err error) {
|
||||||
defer close(dest)
|
defer close(dest)
|
||||||
|
|
|
@ -825,16 +825,15 @@ func EdgesTo(t *testing.T, initIdx func() *index.Index) {
|
||||||
idx := initIdx()
|
idx := initIdx()
|
||||||
id := NewIndexDeps(idx)
|
id := NewIndexDeps(idx)
|
||||||
id.Fataler = t
|
id.Fataler = t
|
||||||
|
defer id.DumpIndex(t)
|
||||||
|
|
||||||
// pn1 ---member---> pn2
|
// pn1 ---member---> pn2
|
||||||
pn1 := id.NewPermanode()
|
pn1 := id.NewPermanode()
|
||||||
pn2 := 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)
|
t.Logf("edge %s --> %s", pn1, pn2)
|
||||||
|
|
||||||
id.DumpIndex(t)
|
|
||||||
|
|
||||||
// Look for pn1
|
// Look for pn1
|
||||||
{
|
{
|
||||||
edges, err := idx.EdgesTo(pn2, nil)
|
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)
|
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) {
|
func Delete(t *testing.T, initIdx func() *index.Index) {
|
||||||
|
|
|
@ -157,6 +157,7 @@ type Edge struct {
|
||||||
FromType string // "permanode", "directory", etc
|
FromType string // "permanode", "directory", etc
|
||||||
FromTitle string // name of source permanode or directory
|
FromTitle string // name of source permanode or directory
|
||||||
To blob.Ref
|
To blob.Ref
|
||||||
|
BlobRef blob.Ref // the blob responsible for the edge relationship
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Edge) String() string {
|
func (e *Edge) String() string {
|
||||||
|
|
Loading…
Reference in New Issue