github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/state/stategen/hot_state_cache.go (about) 1 package stategen 2 3 import ( 4 "sync" 5 6 lru "github.com/hashicorp/golang-lru" 7 "github.com/prometheus/client_golang/prometheus" 8 "github.com/prometheus/client_golang/prometheus/promauto" 9 iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface" 10 ) 11 12 var ( 13 // hotStateCacheSize defines the max number of hot state this can cache. 14 hotStateCacheSize = 32 15 // Metrics 16 hotStateCacheHit = promauto.NewCounter(prometheus.CounterOpts{ 17 Name: "hot_state_cache_hit", 18 Help: "The total number of cache hits on the hot state cache.", 19 }) 20 hotStateCacheMiss = promauto.NewCounter(prometheus.CounterOpts{ 21 Name: "hot_state_cache_miss", 22 Help: "The total number of cache misses on the hot state cache.", 23 }) 24 ) 25 26 // hotStateCache is used to store the processed beacon state after finalized check point.. 27 type hotStateCache struct { 28 cache *lru.Cache 29 lock sync.RWMutex 30 } 31 32 // newHotStateCache initializes the map and underlying cache. 33 func newHotStateCache() *hotStateCache { 34 cache, err := lru.New(hotStateCacheSize) 35 if err != nil { 36 panic(err) 37 } 38 return &hotStateCache{ 39 cache: cache, 40 } 41 } 42 43 // Get returns a cached response via input block root, if any. 44 // The response is copied by default. 45 func (c *hotStateCache) get(root [32]byte) iface.BeaconState { 46 c.lock.RLock() 47 defer c.lock.RUnlock() 48 item, exists := c.cache.Get(root) 49 50 if exists && item != nil { 51 hotStateCacheHit.Inc() 52 return item.(iface.BeaconState).Copy() 53 } 54 hotStateCacheMiss.Inc() 55 return nil 56 } 57 58 // GetWithoutCopy returns a non-copied cached response via input block root. 59 func (c *hotStateCache) getWithoutCopy(root [32]byte) iface.BeaconState { 60 c.lock.RLock() 61 defer c.lock.RUnlock() 62 item, exists := c.cache.Get(root) 63 if exists && item != nil { 64 hotStateCacheHit.Inc() 65 return item.(iface.BeaconState) 66 } 67 hotStateCacheMiss.Inc() 68 return nil 69 } 70 71 // put the response in the cache. 72 func (c *hotStateCache) put(root [32]byte, state iface.BeaconState) { 73 c.lock.Lock() 74 defer c.lock.Unlock() 75 c.cache.Add(root, state) 76 } 77 78 // has returns true if the key exists in the cache. 79 func (c *hotStateCache) has(root [32]byte) bool { 80 c.lock.RLock() 81 defer c.lock.RUnlock() 82 return c.cache.Contains(root) 83 } 84 85 // delete deletes the key exists in the cache. 86 func (c *hotStateCache) delete(root [32]byte) bool { 87 c.lock.Lock() 88 defer c.lock.Unlock() 89 return c.cache.Remove(root) 90 }