// Put inserts a Block into the Cache, returning the Block that was evicted or // nil if no eviction was necessary and the Block was retained. Unused Blocks // are not retained but are returned if the Cache is full. func (c *FIFO) Put(b bgzf.Block) (evicted bgzf.Block, retained bool) { c.mu.Lock() defer c.mu.Unlock() var d bgzf.Block if _, ok := c.table[b.Base()]; ok { return b, false } used := b.Used() if len(c.table) == c.cap { if !used { return b, false } d = c.root.prev.b remove(c.root.prev, c.table) } n := &node{b: b} c.table[b.Base()] = n if used { insertAfter(&c.root, n) } else { insertAfter(c.root.prev, n) } return d, true }
// Put inserts a Block into the Cache, returning the Block that was evicted or // nil if no eviction was necessary and the Block was retained. Unused Blocks // are not retained but are returned if the Cache is full. func (c *Random) Put(b bgzf.Block) (evicted bgzf.Block, retained bool) { c.mu.Lock() defer c.mu.Unlock() var d bgzf.Block if _, ok := c.table[b.Base()]; ok { return b, false } if len(c.table) == c.cap { if !b.Used() { return b, false } for k, v := range c.table { if v.Used() { continue } delete(c.table, k) d = v goto done } for k, v := range c.table { delete(c.table, k) d = v break } done: } c.table[b.Base()] = b return d, true } // StatsRecorder allows a bgzf.Cache to capture cache statistics. type StatsRecorder struct { bgzf.Cache mu sync.RWMutex stats Stats } // Stats represents statistics of a bgzf.Cache. type Stats struct { Gets int // number of Get operations Misses int // number of cache misses Puts int // number of Put operations Retains int // number of times a Put has resulted in Block retention Evictions int // number of times a Put has resulted in a Block eviction } // Stats returns the current statistics for the cache. func (s *StatsRecorder) Stats() Stats { s.mu.RLock() defer s.mu.RUnlock() return s.stats } // Reset zeros the statistics kept by the StatsRecorder. func (s *StatsRecorder) Reset() { s.mu.Lock() s.stats = Stats{} s.mu.Unlock() } // Get returns the Block in the underlying Cache with the specified base or a nil // Block if it does not exist. It updates the gets and misses statistics. func (s *StatsRecorder) Get(base int64) bgzf.Block { s.mu.Lock() s.stats.Gets++ blk := s.Cache.Get(base) if blk == nil { s.stats.Misses++ } s.mu.Unlock() return blk } // Put inserts a Block into the underlying Cache, returning the Block and eviction // status according to the underlying cache behavior. It updates the puts, retains and // evictions statistics. func (s *StatsRecorder) Put(b bgzf.Block) (evicted bgzf.Block, retained bool) { s.mu.Lock() s.stats.Puts++ blk, retained := s.Cache.Put(b) if retained { s.stats.Retains++ if blk != nil { s.stats.Evictions++ } } s.mu.Unlock() return blk, retained }