Go语言进阶之路:手撸一个LRU缓存

一 什么是LRU缓存

LRU(英文:Least Recently Used),中文叫做最近最少使用缓存。也就是说,我们设计一个固定最大容量的缓存,当达到最大容量之后,我们再往缓存里放数据时,会先把最近最少使用的那个元素删除,再放入最新的元素。

 

为什么要设计“固定最大容量的缓存”?在生产环境,每一份内存都是非常宝贵的,如果不设置最大容量上限,元素无休止的增长,总缓存大小势必会达到系统阈值或者内存大小,容易抛出OutOfMemoryError。

二 为什么我们要自己实现LRU缓存

很多语言里面没有开箱即用的LRU缓存工具。包括Java、Python、Go等等。最像LRU缓存的是Java中的LinkedHashMap,它是由HashMap实现的,里面的元素通过链表串起来,但是无法设置最大容量,不断往里面放元素还是会导致它无限制增长。

三 要实现LRU缓存,我们的诉求是什么

从上面的说法,我们得出,我们的LRU缓存需要具备:

  1. 快速存取元素。
  2. 有固定的最大容量,不会无限制增长。
  3. 达到最大容量后,再往缓存里面放入新元素时,会先把最近最少使用的元素删除,再放入新元素。

四 怎么来实现

有了诉求只有,我们的目的很明确,接下来就是如何实现了。

  1. 第一点诉求,快速存取。我们使用map(哈希表、映射)就可以了。
  2. 第二点诉求,固定最大容量。我们给这个map增加capacity(整数)字段来表示最大容量,当map中元素个数达到capacity时,我们要继续往里面放入新元素,则先把最近最少使用的元素删除再放入新元素。
  3. 第三点诉求,删除最近最少使用的元素。怎么找到最近最少使用的元素删除?这个也很简单,参考Java中的LinkedHashMap的做法,把map中的元素使用双向链表串起来,把最近最少使用的元素放在队列尾部,最近最常使用的元素放在头部就可以了。

4.1 设计Entry

我们知道,元素要放入map里面,那我们元素必须具备key和value字段。元素要用双向链表串起来,那元素必须具备pre和next字段。我们的Entry设计如下:

type Entry struct {
  Key   string
  Value interface{}
  pre   *Entry
  next  *Entry
}

4.2 设计缓存

Entry设计完成,我们开始设计缓存。我们自定义缓存类型,里面使用map来存放缓存的元素,cap

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值