github.com/grafana/pyroscope@v1.18.0/pkg/metastore/store/store.go (about)

     1  package store
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  
     7  	"go.etcd.io/bbolt"
     8  )
     9  
    10  var ErrNotFound = errors.New("not found")
    11  
    12  type KV struct {
    13  	Key   []byte
    14  	Value []byte
    15  }
    16  
    17  func NewCursorIter(cursor *bbolt.Cursor) *CursorIterator {
    18  	return &CursorIterator{cursor: cursor}
    19  }
    20  
    21  type CursorIterator struct {
    22  	cursor *bbolt.Cursor
    23  	seek   bool
    24  	k, v   []byte
    25  
    26  	// Prefix that keys must start with.
    27  	Prefix []byte
    28  	// Keys that start with this prefix will be skipped.
    29  	SkipPrefix []byte
    30  }
    31  
    32  func (c *CursorIterator) Next() bool {
    33  	if !c.seek {
    34  		c.k, c.v = c.cursor.Seek(c.Prefix)
    35  		c.seek = true
    36  		return c.valid()
    37  	}
    38  	for {
    39  		c.k, c.v = c.cursor.Next()
    40  		if !c.valid() {
    41  			return false
    42  		}
    43  		if len(c.SkipPrefix) == 0 || !bytes.HasPrefix(c.k, c.SkipPrefix) {
    44  			return true
    45  		}
    46  	}
    47  }
    48  
    49  func (c *CursorIterator) valid() bool {
    50  	return c.k != nil && (len(c.Prefix) == 0 || bytes.HasPrefix(c.k, c.Prefix))
    51  }
    52  
    53  func (c *CursorIterator) At() KV       { return KV{Key: c.k, Value: c.v} }
    54  func (c *CursorIterator) Err() error   { return nil }
    55  func (c *CursorIterator) Close() error { return nil }