欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

golang实现LRU缓存淘汰算法的示例代码

程序员文章站 2022-06-02 22:57:59
lru缓存淘汰算法 lru是最近最少使用策略的缩写,是根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。 双向...

lru缓存淘汰算法

lru是最近最少使用策略的缩写,是根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

双向链表实现lru

将cache的所有位置都用双链表连接起来,当一个位置被访问(get/put)之后,通过调整链表的指向,将该位置调整到链表头的位置,新加入的cache直接加到链表头中。

这样,在多次操作后,最近被访问(get/put)的,就会被向链表头方向移动,而没有访问的,向链表后方移动,链表尾则表示最近最少使用的cache。

当达到缓存容量上限时,链表的最后位置就是最少被访问的cache,我们只需要删除链表最后的cache便可继续添加新的cache。

代码实现

type node struct {
  key int
  value int
  pre *node
  next *node
}

type lrucache struct {
  limit int
  hashmap map[int]*node
  head *node
  end *node
}

func constructor(capacity int) lrucache{
  lrucache := lrucache{limit:capacity}
  lrucache.hashmap = make(map[int]*node, capacity)
  return lrucache
}

func (l *lrucache) get(key int) int {
  if v,ok:= l.hashmap[key];ok {
    l.refreshnode(v)
    return v.value
  }else {
    return -1
  }
}

func (l *lrucache) put(key int, value int) {
  if v,ok := l.hashmap[key];!ok{
    if len(l.hashmap) >= l.limit{
      oldkey := l.removenode(l.head)
      delete(l.hashmap, oldkey)
    }
    node := node{key:key, value:value}
    l.addnode(&node)
    l.hashmap[key] = &node
  }else {
    v.value = value
    l.refreshnode(v)
  }
}

func (l *lrucache) refreshnode(node *node){
  if node == l.end {
    return
  }
  l.removenode(node)
  l.addnode(node)
}

func (l *lrucache) removenode(node *node) int{
  if node == l.end {
    l.end = l.end.pre
  }else if node == l.head {
    l.head = l.head.next
  }else {
    node.pre.next = node.next
    node.next.pre = node.pre
  }
  return node.key
}

func (l *lrucache) addnode(node *node){
  if l.end != nil {
    l.end.next = node
    node.pre = l.end
    node.next = nil
  }
  l.end = node
  if l.head == nil {
    l.head = node
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。