本文主要介绍缓存算法LRU和LFU的简易实现
具体内容
源码
缓存算法LRU和LFU是什么?
- LRU 和LFU算法都是一种缓存淘汰策略
- LRU
- 每次新加入的值放在最前面
- 每次缓存满了,需要删除最老未使用的
- LFU
- 根据使用频率来决定淘汰那些缓存元素
- LRU
LRU和LFU的底层数据结构
- LRU
- 主要是用双向链表和一个Map来实现。
- Map是为了方便随时取用
- 双向链表是为了梳理元素出现的先后顺序
- Map的<key,value>中,value是双向链表的Node节点
- LFU
接口梳理
既然是缓存,管理数据的,那么必然有put()和get()以及delete()接口。
- boolean put(int key, String value):需要考虑元素是否存在,缓存是否满的问题,如果元素已经存在,则需要更新到最新的位置即可。如果元素不存在,则需要需要插入数据到最新的位置,如果缓存已满,则需要清除最老的一个元素,再进行插入更新。
- String get(int key):如果元素不存在,则返回空,存在的话,返回对于元素,并且更新元素只最新位置。
- boolean delete(int x):如果元素不存在,则删除失败。如果元素存在,则进行删除。
LRU既然是管理最近最近数据的,则必然需要考虑对元素顺序,以及最近元素的管理
- String getRecent():获取最近的元素,并重新更新到队尾
- boolean makeRecently(Node4Cache node):更新最近元素
- boolean addRecently(int x, String value):新增最近元素
- boolean deleteLeast():删除最近不使用的元素
双向链表的数据结构设计
考虑到需要一个链表来承接元素的先后顺序,特别是在进行删除第一个元素和插入最后一个元素时,为了查找方便,所以需要在链表内设置一个头节点和一个尾节点,这两个节点是空节点。为了方便查找在两头进行查找,所以需要将链表设置成双向链表。
- 双向链表 DoublyLinked4Cache
- 双向链表节点 Node4Cache
该双向链表需要具备以下功能:
- boolean insertLast(Node4Cache node):将一个元素插入到链表尾部,
- boolean delete(Node4Cache node):删除元素,并梳理节点关系
- Node4Cache deleteOld():删除并返回 链表首元素【当前链表中最早插入的元素】,即头节点指向的那个元素
- Node4Cache getLeast():返回 链表最后一个元素【最新插入的元素】,即尾节点指向的那个元素