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.