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 // TODO: implement
edgeBack map[blob.Ref]map[blob.Ref]bool 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, // when the Value is a blobref. It allows, for example,
// finding the parents of camliMember claims. If a permanode // finding the parents of camliMember claims. If a permanode
// parent set A has a camliMembers B and C, it allows finding // parent set A has a camliMembers B and C, it allows finding
// A from either B and C. // A from either B and C.
// TODO: implement // The slice is not sorted.
edgeBackClaim map[blob.Ref]*camtypes.Claim claimBack map[blob.Ref][]*camtypes.Claim
// TOOD: use deletedCache instead? // TOOD: use deletedCache instead?
deletedBy map[blob.Ref]blob.Ref // key is deleted by value deletedBy map[blob.Ref]blob.Ref // key is deleted by value
@ -159,6 +159,7 @@ func newCorpus() *Corpus {
gps: make(map[blob.Ref]latLong), gps: make(map[blob.Ref]latLong),
mediaTag: make(map[blob.Ref]map[string]string), mediaTag: make(map[blob.Ref]map[string]string),
deletes: make(map[blob.Ref][]deletion), 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. // the end instead), keep this sorted.
sort.Sort(camtypes.ClaimPtrsByDate(pm.Claims)) sort.Sort(camtypes.ClaimPtrsByDate(pm.Claims))
} }
if vbr, ok := blob.Parse(cl.Value); ok {
c.claimBack[vbr] = append(c.claimBack[vbr], &cl)
}
return nil return nil
} }
@ -980,6 +985,22 @@ func (c *Corpus) FileLatLongLocked(fileRef blob.Ref) (lat, long float64, ok bool
return ll.lat, ll.long, true 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 // SetVerboseCorpusLogging controls corpus setup verbosity. It's on by default
// but used to disable verbose logging in tests. // but used to disable verbose logging in tests.
func SetVerboseCorpusLogging(v bool) { func SetVerboseCorpusLogging(v bool) {