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  }