Files
NixMsg/sdk/go/lru.go
T

73 lines
1.2 KiB
Go

package nixmsg
import "container/list"
type lruEntry struct {
key string
val any
}
// lruCache 固定容量 LRU,删除时同步移除链表节点。
type lruCache struct {
cap int
ll *list.List
m map[string]*list.Element
}
func newLRU(cap int) *lruCache {
if cap <= 0 {
cap = 10000
}
return &lruCache{
cap: cap,
ll: list.New(),
m: make(map[string]*list.Element),
}
}
func (c *lruCache) Get(key string) (any, bool) {
el, ok := c.m[key]
if !ok {
return nil, false
}
c.ll.MoveToFront(el)
return el.Value.(*lruEntry).val, true
}
func (c *lruCache) Put(key string, val any) {
if el, ok := c.m[key]; ok {
el.Value.(*lruEntry).val = val
c.ll.MoveToFront(el)
return
}
el := c.ll.PushFront(&lruEntry{key: key, val: val})
c.m[key] = el
for c.ll.Len() > c.cap {
back := c.ll.Back()
if back == nil {
break
}
ent := back.Value.(*lruEntry)
c.ll.Remove(back)
delete(c.m, ent.key)
}
}
func (c *lruCache) Delete(key string) {
el, ok := c.m[key]
if !ok {
return
}
c.ll.Remove(el)
delete(c.m, key)
}
func (c *lruCache) Len() int {
return c.ll.Len()
}
func (c *lruCache) Has(key string) bool {
_, ok := c.m[key]
return ok
}