corpus: reverse-index claims with values that look like blobrefs

Allows efficiently finding parents of permanodes, or permanodes of
file contents, etc.

Adds Corpus.ForeachClaimBackLocked.

Change-Id: I6dffb32eab4a959cd3c5922a7f47d11fdcea5f3d
This commit is contained in:
Brad Fitzpatrick 2014-03-13 18:47:11 -07:00
parent 18bd4cdc0b
commit bf6ae30368
1 changed files with 24 additions and 3 deletions

View File

@ -86,13 +86,13 @@ type Corpus struct {
// TODO: implement
edgeBack map[blob.Ref]map[blob.Ref]bool
// edgeBackClaim allows hopping backwards from a Claim's Value
// claimBack allows hopping backwards from a Claim's Value
// when the Value is a blobref. It allows, for example,
// finding the parents of camliMember claims. If a permanode
// parent set A has a camliMembers B and C, it allows finding
// A from either B and C.
// TODO: implement
edgeBackClaim map[blob.Ref]*camtypes.Claim
// The slice is not sorted.
claimBack map[blob.Ref][]*camtypes.Claim
// TOOD: use deletedCache instead?
deletedBy map[blob.Ref]blob.Ref // key is deleted by value
@ -159,6 +159,7 @@ func newCorpus() *Corpus {
gps: make(map[blob.Ref]latLong),
mediaTag: make(map[blob.Ref]map[string]string),
deletes: make(map[blob.Ref][]deletion),
claimBack: make(map[blob.Ref][]*camtypes.Claim),
}
}
@ -480,6 +481,10 @@ func (c *Corpus) mergeClaimRow(k, v []byte) error {
// the end instead), keep this sorted.
sort.Sort(camtypes.ClaimPtrsByDate(pm.Claims))
}
if vbr, ok := blob.Parse(cl.Value); ok {
c.claimBack[vbr] = append(c.claimBack[vbr], &cl)
}
return nil
}
@ -980,6 +985,22 @@ func (c *Corpus) FileLatLongLocked(fileRef blob.Ref) (lat, long float64, ok bool
return ll.lat, ll.long, true
}
// ForeachClaimBackLocked calls fn for each claim with a value referencing br.
// If at is zero, all claims are yielded.
// If at is non-zero, claims after that point are skipped.
// If fn returns false, iteration ends.
// Iteration is in an undefined order.
func (c *Corpus) ForeachClaimBackLocked(value blob.Ref, at time.Time, fn func(*camtypes.Claim) bool) {
for _, cl := range c.claimBack[value] {
if !at.IsZero() && cl.Date.After(at) {
continue
}
if !fn(cl) {
return
}
}
}
// SetVerboseCorpusLogging controls corpus setup verbosity. It's on by default
// but used to disable verbose logging in tests.
func SetVerboseCorpusLogging(v bool) {