73 lines
1.2 KiB
Go
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
|
|
}
|