golang 实现 lru
package lru
import (
"container/list"
//"github.com/astaxie/beego/validation"
)
type lru struct {
maxSize int64
curSize int64
ll *list.List
cache map[string]*list.Element
}
/*
链表节点中的Value值的结构体
一定要定义一个结构体来存放key和value
因为,在lru中,map的value是指向链表的节点
当我们删除节点的时候,不仅要删除链表中的节点,
还要删除map的值,所以需要从链表中取key,然后反推map,
删除键值对,这样才是完整的删除
*/
type entry struct{
key string
value string
/*
实际使用的时候,value应该定义为interface,
或者是自己声明的一个interface
*/
}
func NewLru(maxSize int64) *lru {
return &lru{
maxSize:maxSize,
}
}
func (lru *lru) get(key string) (s string ,ok bool ){
if e,ok := lru.cache[key]; ok{
lru.ll.MoveToFront(e)
entry := e.Value.(*entry)
return entry.value,true
}
return
}
func (lru *lru) add(key string,value string){
if e,ok:= lru.cache[key];ok {
//更新
lru.ll.MoveToFront(e)
e.Value.(*entry).value = value
} else {
//添加
newE := &entry{key,value}
lru.cache[key] = lru.ll.PushFront(newE)
lru.curSize++
}
for lru.maxSize>0 && lru.curSize > lru.maxSize {
lru.removeOldest()
}
}
func (lru *lru) removeOldest() {
//链表
e:= lru.ll.Back()
lru.ll.Remove(e)
//哈希表
delete(lru.cache,e.Value.(*entry).key)
lru.curSize--
}