github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/consensus/cache.go (about) 1 package consensus 2 3 import ( 4 "container/list" 5 "sync" 6 7 "github.com/nspcc-dev/neo-go/pkg/util" 8 ) 9 10 // relayCache is payload cache which is used to store 11 // last consensus payloads. 12 type relayCache struct { 13 *sync.RWMutex 14 15 maxCap int 16 elems map[util.Uint256]*list.Element 17 queue *list.List 18 } 19 20 // hashable is the type of items which can be stored in the relayCache. 21 type hashable interface { 22 Hash() util.Uint256 23 } 24 25 func newFIFOCache(capacity int) *relayCache { 26 return &relayCache{ 27 RWMutex: new(sync.RWMutex), 28 29 maxCap: capacity, 30 elems: make(map[util.Uint256]*list.Element), 31 queue: list.New(), 32 } 33 } 34 35 // Add adds payload into cache if it doesn't already exist there. 36 func (c *relayCache) Add(p hashable) { 37 c.Lock() 38 defer c.Unlock() 39 40 h := p.Hash() 41 if c.elems[h] != nil { 42 return 43 } 44 45 if c.queue.Len() >= c.maxCap { 46 first := c.queue.Front() 47 c.queue.Remove(first) 48 delete(c.elems, first.Value.(hashable).Hash()) 49 } 50 51 e := c.queue.PushBack(p) 52 c.elems[h] = e 53 } 54 55 // Has checks if the item is already in cache. 56 func (c *relayCache) Has(h util.Uint256) bool { 57 c.RLock() 58 defer c.RUnlock() 59 60 return c.elems[h] != nil 61 } 62 63 // Get returns payload with the specified hash from cache. 64 func (c *relayCache) Get(h util.Uint256) hashable { 65 c.RLock() 66 defer c.RUnlock() 67 68 e, ok := c.elems[h] 69 if !ok { 70 return hashable(nil) 71 } 72 return e.Value.(hashable) 73 }