已完成缓存策略C++17项目 02

Cache-System

一个纯头文件、模板化的缓存策略库。统一接口之下,比较不同访问模式对淘汰策略的影响。

接口形态Header-only · Template
七种策略FIFO · LRU · LFU · LRU-K · ARC
验证方式三类负载 · 固定随机种子

项目做了什么

缓存淘汰不是只有一个“最快算法”。项目在统一的 put / get 接口下实现多种策略,重点观察时间局部性、频率局部性、一次性扫描和工作负载变化对命中率的影响。

库本身没有运行时依赖,使用 C++17 模板让 key 和 value 类型保持通用,适合直接嵌入其他工程。

策略与数据结构

cache_system<Key, Value>        abstract interface
  ├─ RFIFOCache                  queue + hash map
  ├─ RLruCache                   doubly-linked list + hash map
  │    └─ RLruKCache              history cache + main cache
  ├─ RLfuCache                   frequency lists + aging
  ├─ RHashLruCache                sharded LRU instances
  └─ RArcCache                   LRU/LFU regions + ghost queues

其中 ARC 用幽灵队列观察被淘汰 key 的再次访问情况,再动态调整 LRU 与 LFU 区域的容量;Hash-LRU 则把缓存拆成多个分片,降低高并发读场景下的锁竞争范围。

技术取舍

  • 统一接口:让策略可以在同一访问序列下替换,比较结果关注算法差异而不是调用方式差异。
  • 哨兵节点:链表操作不需要为头尾节点写额外的空指针分支,热点路径更清楚。
  • LFU 衰减:历史热点的频次会影响后续负载,因此加入衰减机制,让策略能对变化中的访问模式重新响应。
  • ARC 幽灵队列:只记录淘汰 key,不保存 value,用较小额外空间反馈工作负载变化。

Benchmark

仓库使用固定随机种子和相同单线程请求序列,覆盖热点访问、循环扫描和负载切换三类场景。结果显示:稳定热点下 LFU 命中率最高,负载切换下 LRU-K 表现最好,Hash-LRU 的价值主要体现在降低并发锁竞争。

这组实验的重点不是证明某一个策略永远最好,而是建立“访问模式 → 策略选择”的判断依据;当前尚未覆盖 TTL、持久化、运行时指标和严格的多线程性能基准。