github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/store/cache/cache.go (about) 1 package cache 2 3 import ( 4 "fmt" 5 6 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/cachekv" 7 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/types" 8 9 lru "github.com/hashicorp/golang-lru" 10 ) 11 12 var ( 13 _ types.CommitKVStore = (*CommitKVStoreCache)(nil) 14 _ types.MultiStorePersistentCache = (*CommitKVStoreCacheManager)(nil) 15 16 // DefaultCommitKVStoreCacheSize defines the persistent ARC cache size for a 17 // CommitKVStoreCache. 18 DefaultCommitKVStoreCacheSize uint = 1000 19 ) 20 21 type ( 22 // CommitKVStoreCache implements an inter-block (persistent) cache that wraps a 23 // CommitKVStore. Reads first hit the internal ARC (Adaptive Replacement Cache). 24 // During a cache miss, the read is delegated to the underlying CommitKVStore 25 // and cached. Deletes and writes always happen to both the cache and the 26 // CommitKVStore in a write-through manner. Caching performed in the 27 // CommitKVStore and below is completely irrelevant to this layer. 28 CommitKVStoreCache struct { 29 types.CommitKVStore 30 cache *lru.ARCCache 31 } 32 33 // CommitKVStoreCacheManager maintains a mapping from a StoreKey to a 34 // CommitKVStoreCache. Each CommitKVStore, per StoreKey, is meant to be used 35 // in an inter-block (persistent) manner and typically provided by a 36 // CommitMultiStore. 37 CommitKVStoreCacheManager struct { 38 cacheSize uint 39 caches map[string]types.CommitKVStore 40 } 41 ) 42 43 func NewCommitKVStoreCache(store types.CommitKVStore, size uint) *CommitKVStoreCache { 44 cache, err := lru.NewARC(int(size)) 45 if err != nil { 46 panic(fmt.Errorf("failed to create KVStore cache: %s", err)) 47 } 48 49 return &CommitKVStoreCache{ 50 CommitKVStore: store, 51 cache: cache, 52 } 53 } 54 55 func NewCommitKVStoreCacheManager(size uint) *CommitKVStoreCacheManager { 56 return &CommitKVStoreCacheManager{ 57 cacheSize: size, 58 caches: make(map[string]types.CommitKVStore), 59 } 60 } 61 62 // GetStoreCache returns a Cache from the CommitStoreCacheManager for a given 63 // StoreKey. If no Cache exists for the StoreKey, then one is created and set. 64 // The returned Cache is meant to be used in a persistent manner. 65 func (cmgr *CommitKVStoreCacheManager) GetStoreCache(key types.StoreKey, store types.CommitKVStore) types.CommitKVStore { 66 if cmgr.caches[key.Name()] == nil { 67 cmgr.caches[key.Name()] = NewCommitKVStoreCache(store, cmgr.cacheSize) 68 } 69 70 return cmgr.caches[key.Name()] 71 } 72 73 // Unwrap returns the underlying CommitKVStore for a given StoreKey. 74 func (cmgr *CommitKVStoreCacheManager) Unwrap(key types.StoreKey) types.CommitKVStore { 75 if ckv, ok := cmgr.caches[key.Name()]; ok { 76 return ckv.(*CommitKVStoreCache).CommitKVStore 77 } 78 79 return nil 80 } 81 82 // Reset resets in the internal caches. 83 func (cmgr *CommitKVStoreCacheManager) Reset() { 84 cmgr.caches = make(map[string]types.CommitKVStore) 85 } 86 87 // CacheWrap returns the inter-block cache as a cache-wrapped CommitKVStore. 88 func (ckv *CommitKVStoreCache) CacheWrap() types.CacheWrap { 89 return cachekv.NewStore(ckv) 90 } 91 92 // Get retrieves a value by key. It will first look in the write-through cache. 93 // If the value doesn't exist in the write-through cache, the query is delegated 94 // to the underlying CommitKVStore. 95 func (ckv *CommitKVStoreCache) Get(key []byte) []byte { 96 types.AssertValidKey(key) 97 98 keyStr := string(key) 99 valueI, ok := ckv.cache.Get(keyStr) 100 if ok { 101 // cache hit 102 return valueI.([]byte) 103 } 104 105 // cache miss; write to cache 106 value := ckv.CommitKVStore.Get(key) 107 ckv.cache.Add(keyStr, value) 108 109 return value 110 } 111 112 // Set inserts a key/value pair into both the write-through cache and the 113 // underlying CommitKVStore. 114 func (ckv *CommitKVStoreCache) Set(key, value []byte) { 115 types.AssertValidKey(key) 116 types.AssertValidValue(value) 117 118 ckv.cache.Add(string(key), value) 119 ckv.CommitKVStore.Set(key, value) 120 } 121 122 // Delete removes a key/value pair from both the write-through cache and the 123 // underlying CommitKVStore. 124 func (ckv *CommitKVStoreCache) Delete(key []byte) { 125 ckv.cache.Remove(string(key)) 126 ckv.CommitKVStore.Delete(key) 127 }