分享
  1. 首页
  2. 文章

LRU 算法

lidashuang · · 3200 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

LRU 最近最少使用算法,LRU算法主要用于缓存淘汰。主要目的就是把最近最少使用的数据移除内存,以加载其他数据。

原理

添加元素时,放到链表头
缓存命中,将元素移动到链表头
缓存满了之后,将链表尾的元素删除

LRU算法实现

  • 可以用一个双向链表保存数据
  • 使用hash实现O(1)的访问

groupcache中LRU算法实现(Go语言)
https://github.com/golang/groupcache/blob/master/lru/lru.go

源码简单注释:

package lru
import "container/list"
// Cache 结构体,定义lru cache 不是线程安全的
type Cache struct {
 // 数目限制,0是无限制 
 MaxEntries int
 // 删除时, 可以添加可选的回调函数
 OnEvicted func(key Key, value interface{})
 ll *list.List // 使用链表保存数据
 cache map[interface{}]*list.Element // map 
}
// Key 是任何可以比较的值 http://golang.org/ref/spec#Comparison_operators
type Key interface{}
type entry struct {
 key Key
 value interface{}
}
// 创建新的cache 对象
func New(maxEntries int) *Cache {
 return &Cache{
 MaxEntries: maxEntries,
 ll: list.New(),
 cache: make(map[interface{}]*list.Element),
 }
}
// 添加新的值到cache里
func (c *Cache) Add(key Key, value interface{}) {
 if c.cache == nil {
 c.cache = make(map[interface{}]*list.Element)
 c.ll = list.New()
 }
 if ee, ok := c.cache[key]; ok {
 // 缓存命中移动到链表的头部
 c.ll.MoveToFront(ee)
 ee.Value.(*entry).value = value
 return
 }
 // 添加数据到链表头部
 ele := c.ll.PushFront(&entry{key, value})
 c.cache[key] = ele
 if c.MaxEntries != 0 && c.ll.Len() > c.MaxEntries {
 // 满了删除最后访问的元素
 c.RemoveOldest()
 }
}
// 从cache里获取值.
func (c *Cache) Get(key Key) (value interface{}, ok bool) {
 if c.cache == nil {
 return
 }
 if ele, hit := c.cache[key]; hit {
 // 缓存命中,将命中元素移动到链表头
 c.ll.MoveToFront(ele)
 return ele.Value.(*entry).value, true
 }
 return
}
// 删除指定key的元素
func (c *Cache) Remove(key Key) {
 if c.cache == nil {
 return
 }
 if ele, hit := c.cache[key]; hit {
 c.removeElement(ele)
 }
}
// 删除最后访问的元素
func (c *Cache) RemoveOldest() {
 if c.cache == nil {
 return
 }
 ele := c.ll.Back()
 if ele != nil {
 c.removeElement(ele)
 }
}
func (c *Cache) removeElement(e *list.Element) {
 c.ll.Remove(e)
 kv := e.Value.(*entry)
 delete(c.cache, kv.key)
 if c.OnEvicted != nil {
 c.OnEvicted(kv.key, kv.value)
 }
}
// cache 缓存数
func (c *Cache) Len() int {
 if c.cache == nil {
 return 0
 }
 return c.ll.Len()
}

有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:lidashuang

查看原文:LRU 算法

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
3200 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏