LRU缓存机制
LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。
设计思路
LRU算法需要对数据结构进行查询和插入、删除操作,对序列化数据结构来说,一般采取数组/链表的数据结构。两者差异对比如下:
数组
查询比较快,但是对于增删来说是一个不是一个好的选择链表
查询比较慢,但是对于增删来说十分方便,时间复杂度为O(1)
因此,要想实现快速查询、增删,可以使用hash+链表的形式。hash表存储链表节点,可以在O(1)时间复杂度内查找;链表保持表头的节点是最近使用的节点,表尾的节点是最久为使用节点,这样在淘汰页面的时候直接将链表尾的节点淘汰就可以了,每次访问页面后将其放在链表头。
代码实现
Golang中的双向链表在container/list
这个包下,Go语言标准库中文文档中有详细的介绍,这里不再赘述。
hash表可以直接使用Golang提供的map,这里定义为map[int]*list.Element
类型。其中key
是int
型,表示页面号,*list.Element
表示双向链表的一个节点。
1 | package LRU |