最近最少使用 (LRU) 缓存是一种数据结构,它在内存中维护有限数量的项,并在缓存达到其容量限制时丢弃最近最少使用的项。本文档介绍了 System Design Primer 中 LRU 缓存的实现,重点关注其面向对象设计和关键算法。有关通用缓存策略的信息,请参阅系统设计主题中的“缓存”部分。
LRU 缓存广泛应用于系统设计中,用于:
在本仓库中,LRU 缓存被实现为一个面向对象设计的实践示例,用于演示关键数据结构概念。
来源:solutions/object_oriented_design/lru_cache/lru_cache.ipynb13-29
LRU 缓存的实现结合了两种数据结构:
这种组合允许进行高效操作,在检索和插入方面均达到 O(1) 时间复杂度。
此图显示了 LRU 缓存实现中三个主要类之间的关系。Cache 类协调整体功能,使用LinkedList 来维护顺序,并使用字典(lookup)来提供对缓存项的快速访问。
来源:solutions/object_oriented_design/lru_cache/lru_cache.ipynb54-66 solutions/object_oriented_design/lru_cache/lru_cache.py1-30
Node 类表示缓存中的单个条目
results:存储缓存数据prev:指向链表中前一个节点的引用next:指向链表中下一个节点的引用这是一个标准的双向链表节点,增加了存储任意结果的功能。
来源:solutions/object_oriented_design/lru_cache/lru_cache.ipynb55-60 solutions/object_oriented_design/lru_cache/lru_cache.py1-5
LinkedList 类管理缓存项的顺序
head:指向最近使用的项tail:指向最近最少使用的项它提供了三个关键操作:
move_to_front(node):将现有节点移动到列表头部append_to_front(node):将新节点添加到列表头部remove_from_tail():从尾部移除最近最少使用的节点这些操作共同维护了 LRU 顺序。
来源:solutions/object_oriented_design/lru_cache/lru_cache.ipynb63-71 solutions/object_oriented_design/lru_cache/lru_cache.py8-21
Cache 类整合了哈希表和链表
MAX_SIZE:缓存可以容纳的最大项数size:缓存中当前项数lookup:将查询键映射到节点的字典linked_list:跟踪使用顺序的 LinkedList来源:solutions/object_oriented_design/lru_cache/lru_cache.ipynb74-80 solutions/object_oriented_design/lru_cache/lru_cache.py24-30
LRU 缓存提供两个主要操作:
get(query) 方法从缓存中检索值
来源:solutions/object_oriented_design/lru_cache/lru_cache.ipynb82-91 solutions/object_oriented_design/lru_cache/lru_cache.py32-41
set(results, query) 方法添加或更新缓存条目
来源:solutions/object_oriented_design/lru_cache/lru_cache.ipynb93-116 solutions/object_oriented_design/lru_cache/lru_cache.py43-66
LRU 缓存实现在其操作中实现了最优时间复杂度:
| 操作 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| get(query) | O(1) | O(1) |
| set(results, query) | O(1) | O(1) |
总空间复杂度为 O(n),其中 n 是缓存的最大大小。
当缓存达到容量时,必须淘汰最近最少使用的项,以便为新条目腾出空间。这在set 方法中实现。
该实现首先从查找字典中移除条目,然后从链表尾部移除对应的节点。
来源:solutions/object_oriented_design/lru_cache/lru_cache.ipynb107-110 solutions/object_oriented_design/lru_cache/lru_cache.py57-60
此实现中的 LRU 缓存旨在缓存网页查询结果。典型的使用模式可能如下:
在实际系统中实现 LRU 缓存时,请考虑:
LRU 缓存实现结合了哈希表和双向链表,为检索和插入提供了高效的 O(1) 操作。当达到容量时,它通过淘汰最近最少使用的项来自动管理内存使用,这使其非常适合具有内存限制且访问模式表现出时间局部性的应用程序。