The PermanodeConstraint matching of RelationConstraint.
(ctx context.Context, s *search, pn blob.Ref, at time.Time)
| 816 | |
| 817 | // The PermanodeConstraint matching of RelationConstraint. |
| 818 | func (rc *RelationConstraint) match(ctx context.Context, s *search, pn blob.Ref, at time.Time) (ok bool, err error) { |
| 819 | corpus := s.h.corpus |
| 820 | if corpus == nil { |
| 821 | // TODO: care? |
| 822 | return false, errors.New("RelationConstraint requires an in-memory corpus") |
| 823 | } |
| 824 | |
| 825 | var foreachClaim func(pn blob.Ref, at time.Time, f func(cl *camtypes.Claim) bool) |
| 826 | // relationRef returns the relevant blobRef from the claim if cl defines |
| 827 | // the kind of relation we are looking for, (blob.Ref{}, false) otherwise. |
| 828 | var relationRef func(cl *camtypes.Claim) (blob.Ref, bool) |
| 829 | switch rc.Relation { |
| 830 | case "parent": |
| 831 | foreachClaim = corpus.ForeachClaimBack |
| 832 | relationRef = func(cl *camtypes.Claim) (blob.Ref, bool) { return cl.Permanode, true } |
| 833 | case "child": |
| 834 | foreachClaim = corpus.ForeachClaim |
| 835 | relationRef = func(cl *camtypes.Claim) (blob.Ref, bool) { return blob.Parse(cl.Value) } |
| 836 | default: |
| 837 | panic("bogus") |
| 838 | } |
| 839 | |
| 840 | var matcher matchFn |
| 841 | if rc.Any != nil { |
| 842 | matcher = rc.Any.matcher() |
| 843 | } else { |
| 844 | matcher = rc.All.matcher() |
| 845 | } |
| 846 | |
| 847 | var anyGood bool |
| 848 | var anyBad bool |
| 849 | var lastChecked blob.Ref |
| 850 | var permanodesChecked map[blob.Ref]bool // lazily created to optimize for common case of 1 match |
| 851 | foreachClaim(pn, at, func(cl *camtypes.Claim) bool { |
| 852 | if !rc.matchesAttr(cl.Attr) { |
| 853 | return true // skip claim |
| 854 | } |
| 855 | if lastChecked.Valid() { |
| 856 | if permanodesChecked == nil { |
| 857 | permanodesChecked = make(map[blob.Ref]bool) |
| 858 | } |
| 859 | permanodesChecked[lastChecked] = true |
| 860 | lastChecked = blob.Ref{} // back to zero |
| 861 | } |
| 862 | relRef, ok := relationRef(cl) |
| 863 | if !ok { |
| 864 | // The claim does not define the kind of relation we're looking for |
| 865 | // (e.g. it sets a tag vale), so we continue to the next claim. |
| 866 | return true |
| 867 | } |
| 868 | if permanodesChecked[relRef] { |
| 869 | return true // skip checking |
| 870 | } |
| 871 | if !corpus.PermanodeHasAttrValue(cl.Permanode, at, cl.Attr, cl.Value) { |
| 872 | return true // claim once matched permanode, but no longer |
| 873 | } |
| 874 | |
| 875 | var bm camtypes.BlobMeta |
no test coverage detected