(pred []byte, filter func([]byte) bool)
| 151 | } |
| 152 | |
| 153 | func (lc *LocalCache) Find(pred []byte, filter func([]byte) bool) (uint64, error) { |
| 154 | txn := pstore.NewTransactionAt(lc.startTs, false) |
| 155 | defer txn.Discard() |
| 156 | |
| 157 | attr := string(pred) |
| 158 | |
| 159 | initKey := x.ParsedKey{ |
| 160 | Attr: attr, |
| 161 | } |
| 162 | startKey := x.DataKey(attr, 0) |
| 163 | prefix := initKey.DataPrefix() |
| 164 | |
| 165 | result := &pb.List{} |
| 166 | var prevKey []byte |
| 167 | itOpt := badger.DefaultIteratorOptions |
| 168 | itOpt.PrefetchValues = false |
| 169 | itOpt.AllVersions = true |
| 170 | itOpt.Prefix = prefix |
| 171 | it := txn.NewIterator(itOpt) |
| 172 | defer it.Close() |
| 173 | |
| 174 | for it.Seek(startKey); it.Valid(); { |
| 175 | item := it.Item() |
| 176 | if bytes.Equal(item.Key(), prevKey) { |
| 177 | it.Next() |
| 178 | continue |
| 179 | } |
| 180 | prevKey = append(prevKey[:0], item.Key()...) |
| 181 | |
| 182 | // Parse the key upfront, otherwise ReadPostingList would advance the |
| 183 | // iterator. |
| 184 | pk, err := x.Parse(item.Key()) |
| 185 | if err != nil { |
| 186 | return 0, err |
| 187 | } |
| 188 | |
| 189 | // If we have moved to the next attribute, break |
| 190 | if pk.Attr != attr { |
| 191 | break |
| 192 | } |
| 193 | |
| 194 | if pk.HasStartUid { |
| 195 | // The keys holding parts of a split key should not be accessed here because |
| 196 | // they have a different prefix. However, the check is being added to guard |
| 197 | // against future bugs. |
| 198 | continue |
| 199 | } |
| 200 | |
| 201 | switch { |
| 202 | case item.UserMeta()&BitEmptyPosting > 0: |
| 203 | // This is an empty posting list. So, it should not be included. |
| 204 | continue |
| 205 | default: |
| 206 | // This bit would only be set if there are valid uids in UidPack. |
| 207 | key := x.DataKey(attr, pk.Uid) |
| 208 | pl, err := lc.Get(key) |
| 209 | if err != nil { |
| 210 | return 0, err |
nothing calls this directly
no test coverage detected