LRU cache实现

最久未使用算法(LRU, Least Recently Used)

LRU法是依据各块使用的情况, 总是选择那个最长时间未被使用的块替换。这种方法比较好地反映了程序局部性规律

type cache struct {   
m map
[string]string // 存储k-v nodeM map[string]*node // 存储k对应在链表l中节点的位置 size int l *linkedList // 双向链表,未被使用的越久的越在前面 } type node struct { key string pre *node next *node } type linkedList struct { head *node rear *node } func newLinkedList() *linkedList { return &linkedList{} }
// 双向链表添加节点 func (l
*linkedList) add(n *node) { if l.head == l.rear { l.head = n l.rear = n l.head.next = n l.rear.pre = n return } l.rear.next = n n.pre = l.rear l.rear = n }
// 双向链表删除节点 func (l
*linkedList) delete(n *node) { n.pre.next = n.next n.next.pre = n.pre }
// 双向链表去除头部节点 func (l
*linkedList) pop() string { key := l.head.key l.head = l.head.next l.head.pre = nil return key } func (c *cache) init(size int) { c.m = make(map[string]string, size) c.nodeM = make(map[string]*node, size) c.size = size c.l = newLinkedList() }
func (c
*cache) get(key string) (string, bool) {

// 1.不存在key
if _, ok := c.m[key]; !ok { return "", false }
// 2.存在key,从nodeM中获取节点指针n n :
= c.nodeM[key]

// 更新链表l
c.l.delete(n) c.l.add(n)
return c.m[key], false } func (c *cache) set(key, value string) {
// 1.已经存在这个key,替换k-v
if _, ok := c.m[key]; ok { n := c.nodeM[key] c.l.delete(n) c.l.add(n) c.nodeM[key] = n c.m[key] = value return } //2.不存在这个key,如果cache容量已满需要淘汰最旧的KEY if len(c.m) >= c.size { popKey := c.l.pop() delete(c.m, popKey) delete(c.nodeM, popKey) } // 添加新node newNode := &node{key: key} c.l.add(newNode) c.m[key] = value c.nodeM[key] = newNode } func (c *cache)del(key string){ if _, ok := c.m[key]; !ok { return } n:=c.nodeM[key] c.l.delete(n) delete(c.m, key) delete(c.nodeM, key) }

猜你喜欢

转载自www.cnblogs.com/fwdqxl/p/9317132.html