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 }