github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/storage/prefix.go (about)

     1  package storage
     2  
     3  import (
     4  	"bytes"
     5  
     6  	dbm "github.com/tendermint/tm-db"
     7  	hex "github.com/tmthrgd/go-hex"
     8  )
     9  
    10  type Prefix []byte
    11  
    12  func NewPrefix(bs []byte) Prefix {
    13  	p := make(Prefix, len(bs))
    14  	copy(p, bs)
    15  	return p
    16  }
    17  
    18  func (p Prefix) Key(key []byte) []byte {
    19  	// Avoid any unintended memory sharing between keys
    20  	return append(p[:len(p):len(p)], key...)
    21  }
    22  
    23  func (p Prefix) Suffix(key []byte) []byte {
    24  	bs := make([]byte, len(key)-len(p))
    25  	copy(bs, key[len(p):])
    26  	return bs
    27  }
    28  
    29  // Get the lexicographical sibling above this prefix (i.e. the fixed length integer plus one)
    30  func (p Prefix) Above() []byte {
    31  	for i := len(p) - 1; i >= 0; i-- {
    32  		c := p[i]
    33  		if c < 0xff {
    34  			inc := make([]byte, i+1)
    35  			copy(inc, p)
    36  			inc[i]++
    37  			return inc
    38  		}
    39  	}
    40  	return nil
    41  }
    42  
    43  // Get the lexicographical sibling below this prefix (i.e. the fixed length integer minus one)
    44  func (p Prefix) Below() []byte {
    45  	for i := len(p) - 1; i >= 0; i-- {
    46  		c := p[i]
    47  		if c > 0x00 {
    48  			inc := make([]byte, i+1)
    49  			copy(inc, p)
    50  			inc[i]--
    51  			return inc
    52  		}
    53  	}
    54  	return nil
    55  }
    56  
    57  func (p Prefix) CallbackIterable(source KVCallbackIterable) *prefixCallbackIterable {
    58  	return &prefixCallbackIterable{
    59  		prefix: p,
    60  		source: source,
    61  	}
    62  }
    63  
    64  type prefixCallbackIterable struct {
    65  	prefix Prefix
    66  	source KVCallbackIterable
    67  }
    68  
    69  func (pi *prefixCallbackIterable) Iterate(start, end []byte, ascending bool, fn func(key []byte, value []byte) error) error {
    70  	var pstart, pend []byte = pi.prefix.Key(start), nil
    71  
    72  	if start == nil {
    73  		// We may iterate on a key that does not start with prefix
    74  		pstart = pi.prefix.Below()
    75  	} else {
    76  		pstart = pi.prefix.Key(start)
    77  	}
    78  	if end == nil {
    79  		// Source is exclusive on end so we won't iterate over it
    80  		pend = pi.prefix.Above()
    81  	} else {
    82  		pend = pi.prefix.Key(end)
    83  	}
    84  	return pi.source.Iterate(pstart, pend, ascending, func(key []byte, value []byte) error {
    85  		if bytes.HasPrefix(key, pi.prefix) {
    86  			return fn(pi.prefix.Suffix(key), value)
    87  		}
    88  		return nil
    89  	})
    90  }
    91  
    92  func (p Prefix) Iterator(iteratorFn func(start, end []byte) (dbm.Iterator, error), start, end []byte) (KVIterator, error) {
    93  	var pstart, pend []byte = p.Key(start), nil
    94  
    95  	if end == nil {
    96  		pend = p.Above()
    97  	} else {
    98  		pend = p.Key(end)
    99  	}
   100  
   101  	source, err := iteratorFn(pstart, pend)
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  
   106  	return &prefixIterator{
   107  		start:  start,
   108  		end:    end,
   109  		prefix: p,
   110  		source: source,
   111  	}, nil
   112  }
   113  
   114  func (p Prefix) Iterable(source KVIterable) KVIterable {
   115  	return &prefixIterable{
   116  		prefix: p,
   117  		source: source,
   118  	}
   119  }
   120  
   121  type prefixIterable struct {
   122  	prefix Prefix
   123  	source KVIterable
   124  }
   125  
   126  func (pi *prefixIterable) Iterator(low, high []byte) (KVIterator, error) {
   127  	return pi.prefix.Iterator(pi.source.Iterator, low, high)
   128  }
   129  
   130  func (pi *prefixIterable) ReverseIterator(low, high []byte) (KVIterator, error) {
   131  	return pi.prefix.Iterator(pi.source.ReverseIterator, low, high)
   132  }
   133  
   134  func (p Prefix) Store(source KVStore) KVStore {
   135  	return &prefixKVStore{
   136  		prefix: p,
   137  		source: source,
   138  	}
   139  }
   140  
   141  func (p Prefix) Length() int {
   142  	return len(p)
   143  }
   144  
   145  func (p Prefix) String() string {
   146  	return string(p)
   147  }
   148  
   149  func (p Prefix) HexString() string {
   150  	return hex.EncodeUpperToString(p)
   151  }
   152  
   153  type prefixIterator struct {
   154  	prefix  Prefix
   155  	source  dbm.Iterator
   156  	start   []byte
   157  	end     []byte
   158  	invalid bool
   159  }
   160  
   161  func (pi *prefixIterator) Domain() ([]byte, []byte) {
   162  	return pi.start, pi.end
   163  }
   164  
   165  func (pi *prefixIterator) Valid() bool {
   166  	pi.validate()
   167  	return !pi.invalid && pi.source.Valid()
   168  }
   169  
   170  func (pi *prefixIterator) Next() {
   171  	if pi.invalid {
   172  		panic("prefixIterator.Next() called on invalid iterator")
   173  	}
   174  	pi.source.Next()
   175  	pi.validate()
   176  }
   177  
   178  func (pi *prefixIterator) Key() []byte {
   179  	if pi.invalid {
   180  		panic("prefixIterator.Key() called on invalid iterator")
   181  	}
   182  	return pi.prefix.Suffix(pi.source.Key())
   183  }
   184  
   185  func (pi *prefixIterator) Value() []byte {
   186  	if pi.invalid {
   187  		panic("prefixIterator.Value() called on invalid iterator")
   188  	}
   189  	return pi.source.Value()
   190  }
   191  
   192  func (pi *prefixIterator) Close() error {
   193  	return pi.source.Close()
   194  }
   195  
   196  func (pi *prefixIterator) Error() error {
   197  	return nil
   198  }
   199  
   200  func (pi *prefixIterator) validate() {
   201  	if pi.invalid {
   202  		return
   203  	}
   204  	sourceValid := pi.source.Valid()
   205  	pi.invalid = !sourceValid || !bytes.HasPrefix(pi.source.Key(), pi.prefix)
   206  	if pi.invalid {
   207  		pi.Close()
   208  	}
   209  }
   210  
   211  type prefixKVStore struct {
   212  	prefix Prefix
   213  	source KVStore
   214  }
   215  
   216  func (ps *prefixKVStore) Get(key []byte) ([]byte, error) {
   217  	return ps.source.Get(ps.prefix.Key(key))
   218  }
   219  
   220  func (ps *prefixKVStore) Has(key []byte) (bool, error) {
   221  	return ps.source.Has(ps.prefix.Key(key))
   222  }
   223  
   224  func (ps *prefixKVStore) Set(key, value []byte) error {
   225  	return ps.source.Set(ps.prefix.Key(key), value)
   226  }
   227  
   228  func (ps *prefixKVStore) Delete(key []byte) error {
   229  	return ps.source.Delete(ps.prefix.Key(key))
   230  }
   231  
   232  func (ps *prefixKVStore) Iterator(low, high []byte) (KVIterator, error) {
   233  	return ps.prefix.Iterator(ps.source.Iterator, low, high)
   234  }
   235  
   236  func (ps *prefixKVStore) ReverseIterator(low, high []byte) (KVIterator, error) {
   237  	return ps.prefix.Iterator(ps.source.ReverseIterator, low, high)
   238  }