github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/store/cache/memiterator.go (about) 1 package cache 2 3 import ( 4 "container/list" 5 6 dbm "github.com/gnolang/gno/tm2/pkg/db" 7 "github.com/gnolang/gno/tm2/pkg/std" 8 ) 9 10 // Iterates over iterKVCache items. 11 // if key is nil, means it was deleted. 12 // Implements Iterator. 13 type memIterator struct { 14 start, end []byte 15 items []*std.KVPair 16 ascending bool 17 } 18 19 func newMemIterator(start, end []byte, items *list.List, ascending bool) *memIterator { 20 itemsInDomain := make([]*std.KVPair, 0) 21 var entered bool 22 for e := items.Front(); e != nil; e = e.Next() { 23 item := e.Value.(*std.KVPair) 24 if !dbm.IsKeyInDomain(item.Key, start, end) { 25 if entered { 26 break 27 } 28 continue 29 } 30 itemsInDomain = append(itemsInDomain, item) 31 entered = true 32 } 33 34 return &memIterator{ 35 start: start, 36 end: end, 37 items: itemsInDomain, 38 ascending: ascending, 39 } 40 } 41 42 func (mi *memIterator) Domain() ([]byte, []byte) { 43 return mi.start, mi.end 44 } 45 46 func (mi *memIterator) Valid() bool { 47 return len(mi.items) > 0 48 } 49 50 func (mi *memIterator) assertValid() { 51 if !mi.Valid() { 52 panic("memIterator is invalid") 53 } 54 } 55 56 func (mi *memIterator) Next() { 57 mi.assertValid() 58 if mi.ascending { 59 mi.items = mi.items[1:] 60 } else { 61 mi.items = mi.items[:len(mi.items)-1] 62 } 63 } 64 65 func (mi *memIterator) Key() []byte { 66 mi.assertValid() 67 if mi.ascending { 68 return mi.items[0].Key 69 } 70 return mi.items[len(mi.items)-1].Key 71 } 72 73 func (mi *memIterator) Value() []byte { 74 mi.assertValid() 75 if mi.ascending { 76 return mi.items[0].Value 77 } 78 return mi.items[len(mi.items)-1].Value 79 } 80 81 func (mi *memIterator) Close() { 82 mi.start = nil 83 mi.end = nil 84 mi.items = nil 85 }