github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/store/README.md (about) 1 # Store 2 3 ## CacheKV 4 5 `cachekv.Store` is a wrapper `KVStore` which provides buffered writing / cached reading functionalities over the underlying `KVStore`. 6 7 ```go 8 type Store struct { 9 cache map[string]cValue 10 parent types.KVStore 11 } 12 ``` 13 14 ### Get 15 16 `Store.Get()` checks `Store.cache` first in order to find if there is any cached value associated with the key. If the value exists, the function returns it. If not, the function calls `Store.parent.Get()`, sets the key-value pair to the `Store.cache`, and returns it. 17 18 ### Set 19 20 `Store.Set()` sets the key-value pair to the `Store.cache`. `cValue` has the field `dirty bool` which indicates whether the cached value is different from the underlying value. When `Store.Set()` cache new pair, the `cValue.dirty` is set true so when `Store.Write()` is called it can be written to the underlying store. 21 22 ### Iterator 23 24 `Store.Iterator()` have to traverse on both caches items and the original items. In `Store.iterator()`, two iterators are generated for each of them, and merged. `memIterator` is essentially a slice of the `KVPair`s, used for cached items. `mergeIterator` is a combination of two iterators, where traverse happens ordered on both iterators. 25 26 ## CacheMulti 27 28 `cachemulti.Store` is a wrapper `MultiStore` which provides buffered writing / cached reading functionalities over the underlying `MultiStore` 29 30 ```go 31 type Store struct { 32 db types.CacheKVStore 33 stores map[types.StoreKey] types.CacheWrap 34 } 35 ``` 36 37 `cachemulti.Store` cache wraps all substores in its constructor and hold them in `Store.stores`. `Store.GetKVStore()` returns the store from `Store.stores`, and `Store.Write()` recursively calls `CacheWrap.Write()` on the substores. 38 39 ## DBAdapter 40 41 `dbadapter.Store` is a adapter for `dbm.DB` making it fulfilling the `KVStore` interface. 42 43 ```go 44 type Store struct { 45 dbm.DB 46 } 47 ``` 48 49 `dbadapter.Store` embeds `dbm.DB`, so most of the `KVStore` interface functions are implemented. The other functions(mostly miscellaneous) are manually implemented. 50 51 ## IAVL 52 53 `iavl.Store` is a base-layer self-balancing merkle tree. It is guaranteed that 54 55 1. Get & set operations are `O(log n)`, where `n` is the number of elements in the tree 56 2. Iteration efficiently returns the sorted elements within the range 57 3. Each tree version is immutable and can be retrieved even after a commit(depending on the pruning settings) 58 59 Specification and implementation of IAVL tree can be found in [https://github.com/tendermint/classic/iavl]. 60 61 ## GasKV 62 63 `gaskv.Store` is a wrapper `KVStore` which provides gas consuming functionalities over the underlying `KVStore`. 64 65 ```go 66 type Store struct { 67 gasMeter types.GasMeter 68 gasConfig types.GasConfig 69 parent types.KVStore 70 } 71 ``` 72 73 When each `KVStore` methods are called, `gaskv.Store` automatically consumes appropriate amount of gas depending on the `Store.gasConfig`. 74 75 76 ## Prefix 77 78 `prefix.Store` is a wrapper `KVStore` which provides automatic key-prefixing functionalities over the underlying `KVStore`. 79 80 ```go 81 type Store struct { 82 parent types.KVStore 83 prefix []byte 84 } 85 ``` 86 87 When `Store.{Get, Set}()` is called, the store forwards the call to its parent, with the key prefixed with the `Store.prefix`. 88 89 When `Store.Iterator()` is called, it does not simply prefix the `Store.prefix`, since it does not work as intended. In that case, some of the elements are traversed even they are not starting with the prefix. 90 91 ## RootMulti 92 93 `rootmulti.Store` is a base-layer `MultiStore` where multiple `KVStore` can be mounted on it and retrieved via object-capability keys. The keys are memory addresses, so it is impossible to forge the key unless an object is a valid owner(or a receiver) of the key, according to the object capability principles. 94 95 ## TraceKV 96 97 `tracekv.Store` is a wrapper `KVStore` which provides operation tracing functionalities over the underlying `KVStore`. 98 99 ```go 100 type Store struct { 101 parent types.KVStore 102 writer io.Writer 103 context types.TraceContext 104 } 105 ``` 106 107 When each `KVStore` methods are called, `tracekv.Store` automatically logs `traceOperation` to the `Store.writer`. 108 109 ```go 110 type traceOperation struct { 111 Operation operation 112 Key string 113 Value string 114 Metadata map[string]interface{} 115 } 116 ``` 117 118 `traceOperation.Metadata` is filled with `Store.context` when it is not nil. `TraceContext` is a `map[string]interface{}`. 119 120 ## Transient 121 122 `transient.Store` is a base-layer `KVStore` which is automatically discarded at the end of the block. 123 124 ```go 125 type Store struct { 126 dbadapter.Store 127 } 128 ``` 129 130 `Store.Store` is a `dbadapter.Store` with a `memdb.NewMemDB()`. All `KVStore` methods are reused. When `Store.Commit()` is called, new `dbadapter.Store` is assigned, discarding previous reference and making it garbage collected.