github.com/koko1123/flow-go-1@v0.29.6/module/mempool/queue/heroQueue.go (about) 1 package queue 2 3 import ( 4 "sync" 5 6 "github.com/rs/zerolog" 7 8 "github.com/koko1123/flow-go-1/model/flow" 9 "github.com/koko1123/flow-go-1/module" 10 herocache "github.com/koko1123/flow-go-1/module/mempool/herocache/backdata" 11 "github.com/koko1123/flow-go-1/module/mempool/herocache/backdata/heropool" 12 ) 13 14 // HeroQueue implements a HeroCache-based in-memory queue. 15 // HeroCache is a key-value cache with zero heap allocation and optimized Garbage Collection. 16 type HeroQueue struct { 17 mu sync.RWMutex 18 cache *herocache.Cache 19 sizeLimit uint 20 } 21 22 func NewHeroQueue(sizeLimit uint32, logger zerolog.Logger, collector module.HeroCacheMetrics) *HeroQueue { 23 return &HeroQueue{ 24 cache: herocache.NewCache( 25 sizeLimit, 26 herocache.DefaultOversizeFactor, 27 heropool.NoEjection, 28 logger.With().Str("mempool", "hero-queue").Logger(), 29 collector), 30 sizeLimit: uint(sizeLimit), 31 } 32 } 33 34 // Push stores the entity into the queue. 35 // Boolean returned variable determines whether push was successful, i.e., 36 // push may be dropped if queue is full or already exists. 37 func (c *HeroQueue) Push(entity flow.Entity) bool { 38 c.mu.Lock() 39 defer c.mu.Unlock() 40 41 if c.cache.Size() >= c.sizeLimit { 42 // we check size before attempt on a push, 43 // although HeroCache is on no-ejection mode and discards pushes beyond limit, 44 // we save an id computation by just checking the size here. 45 return false 46 } 47 48 return c.cache.Add(entity.ID(), entity) 49 } 50 51 // Pop removes and returns the head of queue, and updates the head to the next element. 52 // Boolean return value determines whether pop is successful, i.e., popping an empty queue returns false. 53 func (c *HeroQueue) Pop() (flow.Entity, bool) { 54 c.mu.Lock() 55 defer c.mu.Unlock() 56 57 head, ok := c.cache.Head() 58 if !ok { 59 // cache is empty, and there is no head yet to pop. 60 return nil, false 61 } 62 63 c.cache.Remove(head.ID()) 64 return head, true 65 } 66 67 func (c *HeroQueue) Size() uint { 68 c.mu.RLock() 69 defer c.mu.RUnlock() 70 71 return c.cache.Size() 72 }