github.com/Finschia/finschia-sdk@v0.48.1/store/cachekv/memiterator.go (about) 1 package cachekv 2 3 import ( 4 "bytes" 5 6 dbm "github.com/tendermint/tm-db" 7 8 "github.com/Finschia/finschia-sdk/store/types" 9 ) 10 11 // Iterates over iterKVCache items. 12 // if key is nil, means it was deleted. 13 // Implements Iterator. 14 type memIterator struct { 15 types.Iterator 16 17 lastKey []byte 18 deleted map[string]struct{} 19 } 20 21 func IsKeyInDomain(key, start, end []byte) bool { 22 if bytes.Compare(key, start) < 0 { 23 return false 24 } 25 if end != nil && bytes.Compare(end, key) <= 0 { 26 return false 27 } 28 return true 29 } 30 31 func newMemIterator(start, end []byte, items *dbm.MemDB, deleted map[string]struct{}, ascending bool) *memIterator { 32 var iter types.Iterator 33 var err error 34 35 if ascending { 36 iter, err = items.Iterator(start, end) 37 } else { 38 iter, err = items.ReverseIterator(start, end) 39 } 40 41 if err != nil { 42 panic(err) 43 } 44 45 return &memIterator{ 46 Iterator: iter, 47 48 lastKey: nil, 49 deleted: deleted, 50 } 51 } 52 53 func (mi *memIterator) Value() []byte { 54 key := mi.Iterator.Key() 55 // We need to handle the case where deleted is modified and includes our current key 56 // We handle this by maintaining a lastKey object in the iterator. 57 // If the current key is the same as the last key (and last key is not nil / the start) 58 // then we are calling value on the same thing as last time. 59 // Therefore we don't check the mi.deleted to see if this key is included in there. 60 reCallingOnOldLastKey := (mi.lastKey != nil) && bytes.Equal(key, mi.lastKey) 61 if _, ok := mi.deleted[string(key)]; ok && !reCallingOnOldLastKey { 62 return nil 63 } 64 mi.lastKey = key 65 return mi.Iterator.Value() 66 }