github.com/Finschia/finschia-sdk@v0.48.1/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 `MutliStore` 29 30 ```go 31 type Store struct { 32 db types.CacheKVStore 33 stores map[types.StoreKey] types.CacheWrap 34 } 35 ``` 36 37 `cachemulti.Store` branches 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/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 ## Prefix 76 77 `prefix.Store` is a wrapper `KVStore` which provides automatic key-prefixing functionalities over the underlying `KVStore`. 78 79 ```go 80 type Store struct { 81 parent types.KVStore 82 prefix []byte 83 } 84 ``` 85 86 When `Store.{Get, Set}()` is called, the store forwards the call to its parent, with the key prefixed with the `Store.prefix`. 87 88 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. 89 90 ## RootMulti 91 92 `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. 93 94 ## TraceKV 95 96 `tracekv.Store` is a wrapper `KVStore` which provides operation tracing functionalities over the underlying `KVStore`. 97 98 ```go 99 type Store struct { 100 parent types.KVStore 101 writer io.Writer 102 context types.TraceContext 103 } 104 ``` 105 106 When each `KVStore` methods are called, `tracekv.Store` automatically logs `traceOperation` to the `Store.writer`. 107 108 ```go 109 type traceOperation struct { 110 Operation operation 111 Key string 112 Value string 113 Metadata map[string]interface{} 114 } 115 ``` 116 117 `traceOperation.Metadata` is filled with `Store.context` when it is not nil. `TraceContext` is a `map[string]interface{}`. 118 119 ## Transient 120 121 `transient.Store` is a base-layer `KVStore` which is automatically discarded at the end of the block. 122 123 ```go 124 type Store struct { 125 dbadapter.Store 126 } 127 ``` 128 129 `Store.Store` is a `dbadapter.Store` with a `dbm.NewMemDB()`. All `KVStore` methods are reused. When `Store.Commit()` is called, new `dbadapter.Store` is assigned, discarding previous reference and making it garbage collected.