mirror of https://github.com/poanetwork/gecko.git
94 lines
1.7 KiB
Go
94 lines
1.7 KiB
Go
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package cache
|
|
|
|
import (
|
|
"container/list"
|
|
"sync"
|
|
)
|
|
|
|
// EvictableLRU is an LRU cache that notifies the objects when they are evicted.
|
|
type EvictableLRU struct {
|
|
lock sync.Mutex
|
|
entryMap map[[32]byte]*list.Element
|
|
entryList *list.List
|
|
Size int
|
|
}
|
|
|
|
// Deduplicate implements the Deduplicator interface
|
|
func (c *EvictableLRU) Deduplicate(value Evictable) Evictable {
|
|
c.lock.Lock()
|
|
defer c.lock.Unlock()
|
|
|
|
return c.deduplicate(value)
|
|
}
|
|
|
|
// Flush implements the Deduplicator interface
|
|
func (c *EvictableLRU) Flush() {
|
|
c.lock.Lock()
|
|
defer c.lock.Unlock()
|
|
|
|
c.flush()
|
|
}
|
|
|
|
func (c *EvictableLRU) init() {
|
|
if c.entryMap == nil {
|
|
c.entryMap = make(map[[32]byte]*list.Element)
|
|
}
|
|
if c.entryList == nil {
|
|
c.entryList = list.New()
|
|
}
|
|
if c.Size <= 0 {
|
|
c.Size = 1
|
|
}
|
|
}
|
|
|
|
func (c *EvictableLRU) resize() {
|
|
for c.entryList.Len() > c.Size {
|
|
e := c.entryList.Front()
|
|
c.entryList.Remove(e)
|
|
|
|
val := e.Value.(Evictable)
|
|
delete(c.entryMap, val.ID().Key())
|
|
val.Evict()
|
|
}
|
|
}
|
|
|
|
func (c *EvictableLRU) deduplicate(value Evictable) Evictable {
|
|
c.init()
|
|
c.resize()
|
|
|
|
key := value.ID().Key()
|
|
if e, ok := c.entryMap[key]; !ok {
|
|
if c.entryList.Len() >= c.Size {
|
|
e = c.entryList.Front()
|
|
c.entryList.MoveToBack(e)
|
|
|
|
val := e.Value.(Evictable)
|
|
delete(c.entryMap, val.ID().Key())
|
|
val.Evict()
|
|
|
|
e.Value = value
|
|
} else {
|
|
e = c.entryList.PushBack(value)
|
|
}
|
|
c.entryMap[key] = e
|
|
} else {
|
|
c.entryList.MoveToBack(e)
|
|
|
|
val := e.Value.(Evictable)
|
|
value = val
|
|
}
|
|
return value
|
|
}
|
|
|
|
func (c *EvictableLRU) flush() {
|
|
c.init()
|
|
|
|
size := c.Size
|
|
c.Size = 0
|
|
c.resize()
|
|
c.Size = size
|
|
}
|