github.com/nitinawathare/ethereumassignment3@v0.0.0-20211021213010-f07344c2b868/go-ethereum/swarm/shed/index.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package shed 18 19 import ( 20 "bytes" 21 22 "github.com/syndtr/goleveldb/leveldb" 23 "github.com/syndtr/goleveldb/leveldb/iterator" 24 ) 25 26 // Item holds fields relevant to Swarm Chunk data and metadata. 27 // All information required for swarm storage and operations 28 // on that storage must be defined here. 29 // This structure is logically connected to swarm storage, 30 // the only part of this package that is not generalized, 31 // mostly for performance reasons. 32 // 33 // Item is a type that is used for retrieving, storing and encoding 34 // chunk data and metadata. It is passed as an argument to Index encoding 35 // functions, get function and put function. 36 // But it is also returned with additional data from get function call 37 // and as the argument in iterator function definition. 38 type Item struct { 39 Address []byte 40 Data []byte 41 AccessTimestamp int64 42 StoreTimestamp int64 43 // UseMockStore is a pointer to identify 44 // an unset state of the field in Join function. 45 UseMockStore *bool 46 } 47 48 // Merge is a helper method to construct a new 49 // Item by filling up fields with default values 50 // of a particular Item with values from another one. 51 func (i Item) Merge(i2 Item) (new Item) { 52 if i.Address == nil { 53 i.Address = i2.Address 54 } 55 if i.Data == nil { 56 i.Data = i2.Data 57 } 58 if i.AccessTimestamp == 0 { 59 i.AccessTimestamp = i2.AccessTimestamp 60 } 61 if i.StoreTimestamp == 0 { 62 i.StoreTimestamp = i2.StoreTimestamp 63 } 64 if i.UseMockStore == nil { 65 i.UseMockStore = i2.UseMockStore 66 } 67 return i 68 } 69 70 // Index represents a set of LevelDB key value pairs that have common 71 // prefix. It holds functions for encoding and decoding keys and values 72 // to provide transparent actions on saved data which inclide: 73 // - getting a particular Item 74 // - saving a particular Item 75 // - iterating over a sorted LevelDB keys 76 // It implements IndexIteratorInterface interface. 77 type Index struct { 78 db *DB 79 prefix []byte 80 encodeKeyFunc func(fields Item) (key []byte, err error) 81 decodeKeyFunc func(key []byte) (e Item, err error) 82 encodeValueFunc func(fields Item) (value []byte, err error) 83 decodeValueFunc func(keyFields Item, value []byte) (e Item, err error) 84 } 85 86 // IndexFuncs structure defines functions for encoding and decoding 87 // LevelDB keys and values for a specific index. 88 type IndexFuncs struct { 89 EncodeKey func(fields Item) (key []byte, err error) 90 DecodeKey func(key []byte) (e Item, err error) 91 EncodeValue func(fields Item) (value []byte, err error) 92 DecodeValue func(keyFields Item, value []byte) (e Item, err error) 93 } 94 95 // NewIndex returns a new Index instance with defined name and 96 // encoding functions. The name must be unique and will be validated 97 // on database schema for a key prefix byte. 98 func (db *DB) NewIndex(name string, funcs IndexFuncs) (f Index, err error) { 99 id, err := db.schemaIndexPrefix(name) 100 if err != nil { 101 return f, err 102 } 103 prefix := []byte{id} 104 return Index{ 105 db: db, 106 prefix: prefix, 107 // This function adjusts Index LevelDB key 108 // by appending the provided index id byte. 109 // This is needed to avoid collisions between keys of different 110 // indexes as all index ids are unique. 111 encodeKeyFunc: func(e Item) (key []byte, err error) { 112 key, err = funcs.EncodeKey(e) 113 if err != nil { 114 return nil, err 115 } 116 return append(append(make([]byte, 0, len(key)+1), prefix...), key...), nil 117 }, 118 // This function reverses the encodeKeyFunc constructed key 119 // to transparently work with index keys without their index ids. 120 // It assumes that index keys are prefixed with only one byte. 121 decodeKeyFunc: func(key []byte) (e Item, err error) { 122 return funcs.DecodeKey(key[1:]) 123 }, 124 encodeValueFunc: funcs.EncodeValue, 125 decodeValueFunc: funcs.DecodeValue, 126 }, nil 127 } 128 129 // Get accepts key fields represented as Item to retrieve a 130 // value from the index and return maximum available information 131 // from the index represented as another Item. 132 func (f Index) Get(keyFields Item) (out Item, err error) { 133 key, err := f.encodeKeyFunc(keyFields) 134 if err != nil { 135 return out, err 136 } 137 value, err := f.db.Get(key) 138 if err != nil { 139 return out, err 140 } 141 out, err = f.decodeValueFunc(keyFields, value) 142 if err != nil { 143 return out, err 144 } 145 return out.Merge(keyFields), nil 146 } 147 148 // Has accepts key fields represented as Item to check 149 // if there this Item's encoded key is stored in 150 // the index. 151 func (f Index) Has(keyFields Item) (bool, error) { 152 key, err := f.encodeKeyFunc(keyFields) 153 if err != nil { 154 return false, err 155 } 156 return f.db.Has(key) 157 } 158 159 // Put accepts Item to encode information from it 160 // and save it to the database. 161 func (f Index) Put(i Item) (err error) { 162 key, err := f.encodeKeyFunc(i) 163 if err != nil { 164 return err 165 } 166 value, err := f.encodeValueFunc(i) 167 if err != nil { 168 return err 169 } 170 return f.db.Put(key, value) 171 } 172 173 // PutInBatch is the same as Put method, but it just 174 // saves the key/value pair to the batch instead 175 // directly to the database. 176 func (f Index) PutInBatch(batch *leveldb.Batch, i Item) (err error) { 177 key, err := f.encodeKeyFunc(i) 178 if err != nil { 179 return err 180 } 181 value, err := f.encodeValueFunc(i) 182 if err != nil { 183 return err 184 } 185 batch.Put(key, value) 186 return nil 187 } 188 189 // Delete accepts Item to remove a key/value pair 190 // from the database based on its fields. 191 func (f Index) Delete(keyFields Item) (err error) { 192 key, err := f.encodeKeyFunc(keyFields) 193 if err != nil { 194 return err 195 } 196 return f.db.Delete(key) 197 } 198 199 // DeleteInBatch is the same as Delete just the operation 200 // is performed on the batch instead on the database. 201 func (f Index) DeleteInBatch(batch *leveldb.Batch, keyFields Item) (err error) { 202 key, err := f.encodeKeyFunc(keyFields) 203 if err != nil { 204 return err 205 } 206 batch.Delete(key) 207 return nil 208 } 209 210 // IndexIterFunc is a callback on every Item that is decoded 211 // by iterating on an Index keys. 212 // By returning a true for stop variable, iteration will 213 // stop, and by returning the error, that error will be 214 // propagated to the called iterator method on Index. 215 type IndexIterFunc func(item Item) (stop bool, err error) 216 217 // IterateOptions defines optional parameters for Iterate function. 218 type IterateOptions struct { 219 // StartFrom is the Item to start the iteration from. 220 StartFrom *Item 221 // If SkipStartFromItem is true, StartFrom item will not 222 // be iterated on. 223 SkipStartFromItem bool 224 // Iterate over items which keys have a common prefix. 225 Prefix []byte 226 } 227 228 // Iterate function iterates over keys of the Index. 229 // If IterateOptions is nil, the iterations is over all keys. 230 func (f Index) Iterate(fn IndexIterFunc, options *IterateOptions) (err error) { 231 if options == nil { 232 options = new(IterateOptions) 233 } 234 // construct a prefix with Index prefix and optional common key prefix 235 prefix := append(f.prefix, options.Prefix...) 236 // start from the prefix 237 startKey := prefix 238 if options.StartFrom != nil { 239 // start from the provided StartFrom Item key value 240 startKey, err = f.encodeKeyFunc(*options.StartFrom) 241 if err != nil { 242 return err 243 } 244 } 245 it := f.db.NewIterator() 246 defer it.Release() 247 248 // move the cursor to the start key 249 ok := it.Seek(startKey) 250 if !ok { 251 // stop iterator if seek has failed 252 return it.Error() 253 } 254 if options.SkipStartFromItem && bytes.Equal(startKey, it.Key()) { 255 // skip the start from Item if it is the first key 256 // and it is explicitly configured to skip it 257 ok = it.Next() 258 } 259 for ; ok; ok = it.Next() { 260 item, err := f.itemFromIterator(it, prefix) 261 if err != nil { 262 if err == leveldb.ErrNotFound { 263 break 264 } 265 return err 266 } 267 stop, err := fn(item) 268 if err != nil { 269 return err 270 } 271 if stop { 272 break 273 } 274 } 275 return it.Error() 276 } 277 278 // First returns the first item in the Index which encoded key starts with a prefix. 279 // If the prefix is nil, the first element of the whole index is returned. 280 // If Index has no elements, a leveldb.ErrNotFound error is returned. 281 func (f Index) First(prefix []byte) (i Item, err error) { 282 it := f.db.NewIterator() 283 defer it.Release() 284 285 totalPrefix := append(f.prefix, prefix...) 286 it.Seek(totalPrefix) 287 288 return f.itemFromIterator(it, totalPrefix) 289 } 290 291 // itemFromIterator returns the Item from the current iterator position. 292 // If the complete encoded key does not start with totalPrefix, 293 // leveldb.ErrNotFound is returned. Value for totalPrefix must start with 294 // Index prefix. 295 func (f Index) itemFromIterator(it iterator.Iterator, totalPrefix []byte) (i Item, err error) { 296 key := it.Key() 297 if !bytes.HasPrefix(key, totalPrefix) { 298 return i, leveldb.ErrNotFound 299 } 300 // create a copy of key byte slice not to share leveldb underlaying slice array 301 keyItem, err := f.decodeKeyFunc(append([]byte(nil), key...)) 302 if err != nil { 303 return i, err 304 } 305 // create a copy of value byte slice not to share leveldb underlaying slice array 306 valueItem, err := f.decodeValueFunc(keyItem, append([]byte(nil), it.Value()...)) 307 if err != nil { 308 return i, err 309 } 310 return keyItem.Merge(valueItem), it.Error() 311 } 312 313 // Last returns the last item in the Index which encoded key starts with a prefix. 314 // If the prefix is nil, the last element of the whole index is returned. 315 // If Index has no elements, a leveldb.ErrNotFound error is returned. 316 func (f Index) Last(prefix []byte) (i Item, err error) { 317 it := f.db.NewIterator() 318 defer it.Release() 319 320 // get the next prefix in line 321 // since leveldb iterator Seek seeks to the 322 // next key if the key that it seeks to is not found 323 // and by getting the previous key, the last one for the 324 // actual prefix is found 325 nextPrefix := incByteSlice(prefix) 326 l := len(prefix) 327 328 if l > 0 && nextPrefix != nil { 329 it.Seek(append(f.prefix, nextPrefix...)) 330 it.Prev() 331 } else { 332 it.Last() 333 } 334 335 totalPrefix := append(f.prefix, prefix...) 336 return f.itemFromIterator(it, totalPrefix) 337 } 338 339 // incByteSlice returns the byte slice of the same size 340 // of the provided one that is by one incremented in its 341 // total value. If all bytes in provided slice are equal 342 // to 255 a nil slice would be returned indicating that 343 // increment can not happen for the same length. 344 func incByteSlice(b []byte) (next []byte) { 345 l := len(b) 346 next = make([]byte, l) 347 copy(next, b) 348 for i := l - 1; i >= 0; i-- { 349 if b[i] == 255 { 350 next[i] = 0 351 } else { 352 next[i] = b[i] + 1 353 return next 354 } 355 } 356 return nil 357 } 358 359 // Count returns the number of items in index. 360 func (f Index) Count() (count int, err error) { 361 it := f.db.NewIterator() 362 defer it.Release() 363 364 for ok := it.Seek(f.prefix); ok; ok = it.Next() { 365 key := it.Key() 366 if key[0] != f.prefix[0] { 367 break 368 } 369 count++ 370 } 371 return count, it.Error() 372 } 373 374 // CountFrom returns the number of items in index keys 375 // starting from the key encoded from the provided Item. 376 func (f Index) CountFrom(start Item) (count int, err error) { 377 startKey, err := f.encodeKeyFunc(start) 378 if err != nil { 379 return 0, err 380 } 381 it := f.db.NewIterator() 382 defer it.Release() 383 384 for ok := it.Seek(startKey); ok; ok = it.Next() { 385 key := it.Key() 386 if key[0] != f.prefix[0] { 387 break 388 } 389 count++ 390 } 391 return count, it.Error() 392 }