You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
1.5 KiB
Go

2 years ago
package lru
import (
"container/list"
"sync"
)
type node struct {
k interface{}
v interface{}
}
type LRU struct {
mutex sync.RWMutex
maxLen int // if maxLen<=0 then no limit
lruList *list.List
datas map[interface{}]*list.Element
}
func New(maxLen int) *LRU {
return &LRU{
maxLen: maxLen,
lruList: list.New(),
datas: make(map[interface{}]*list.Element),
}
}
func (lc *LRU) PushFront(k, v interface{}) {
lc.mutex.Lock()
defer lc.mutex.Unlock()
if e, ok := lc.datas[k]; ok {
e.Value.(*node).v = v
lc.lruList.MoveToFront(e)
} else {
e := lc.lruList.PushFront(&node{k, v})
lc.datas[k] = e
}
if lc.maxLen > 0 && lc.lruList.Len() > lc.maxLen {
lc.popTail()
}
}
func (lc *LRU) PopTail() (interface{}, bool) {
lc.mutex.Lock()
defer lc.mutex.Unlock()
return lc.popTail()
}
func (lc *LRU) Get(k interface{}) (interface{}, bool) {
lc.mutex.Lock()
defer lc.mutex.Unlock()
if e, ok := lc.datas[k]; ok {
lc.lruList.MoveToFront(e)
return e.Value.(*node).v, ok
}
return nil, false
}
func (lc *LRU) Del(k interface{}) {
lc.mutex.Lock()
defer lc.mutex.Unlock()
lc.del(k)
}
func (lc *LRU) Len() int {
lc.mutex.RLock()
defer lc.mutex.RUnlock()
return lc.lruList.Len()
}
func (lc *LRU) popTail() (interface{}, bool) {
e := lc.lruList.Back()
if e != nil {
lc.del(e.Value.(*node).k)
return e.Value.(*node).v, true
}
return nil, false
}
func (lc *LRU) del(k interface{}) {
if e, ok := lc.datas[k]; ok {
delete(lc.datas, k)
lc.lruList.Remove(e)
}
}