github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/kv/scan.go (about) 1 package kv 2 3 import ( 4 "bytes" 5 "context" 6 ) 7 8 type PrefixIterator struct { 9 Iterator EntriesIterator 10 Prefix []byte 11 PartitionKey []byte 12 completed bool 13 } 14 15 func (b *PrefixIterator) Next() bool { 16 if b.completed { 17 return false 18 } 19 if !b.Iterator.Next() { 20 b.completed = true 21 return false 22 } 23 entry := b.Iterator.Entry() 24 if !bytes.HasPrefix(entry.Key, b.Prefix) { 25 b.completed = true 26 return false 27 } 28 return true 29 } 30 31 func (b *PrefixIterator) SeekGE(key []byte) { 32 b.Iterator.SeekGE(key) 33 b.completed = false 34 } 35 36 func (b *PrefixIterator) Entry() *Entry { 37 if b.completed { 38 return nil 39 } 40 return b.Iterator.Entry() 41 } 42 43 func (b *PrefixIterator) Err() error { 44 return b.Iterator.Err() 45 } 46 47 func (b *PrefixIterator) Close() { 48 b.Iterator.Close() 49 } 50 51 // ScanPrefix returns an iterator on store that scan the set of keys that start with prefix 52 // after is the full key name for which to start the scan from 53 func ScanPrefix(ctx context.Context, store Store, partitionKey, prefix, after []byte) (EntriesIterator, error) { 54 start := prefix 55 if len(after) > 0 && string(after) > string(prefix) { 56 start = after 57 } 58 iter, err := store.Scan(ctx, partitionKey, ScanOptions{ 59 KeyStart: start, 60 }) 61 if err != nil { 62 return nil, err 63 } 64 return &PrefixIterator{ 65 Iterator: iter, 66 Prefix: prefix, 67 PartitionKey: partitionKey, 68 }, nil 69 }