当前位置: 首页 > backend >正文

一个简单的带TTL的LRU的C++实现

实际上这个实现还是有点小问题,因为cv.notify之后不一定能保证线程立刻执行,因此有可能进入put方法后有个元素过期导致空了一个位置出来,因此在判断元素满了的分支里还需要手动清理一下,但是懒得改了(

using namespace std::chrono;
using namespace std::chrono_literals;class LRUCache {
private:struct Node {int key, value;steady_clock::time_point ttl;int version;std::shared_ptr<Node> next;std::weak_ptr<Node> prev;Node(): key(0), value(0), ttl(steady_clock::time_point{}), version(0), next(nullptr) {prev.reset();}Node(int x, int y): key(x), value(y), ttl(steady_clock::time_point{}), version(0), next(nullptr) {prev.reset();}Node(int x, int y, int z): key(x), value(y), ttl(steady_clock::time_point{}), version(z), next(nullptr) {prev.reset();}};struct Task {steady_clock::time_point ttl;int key, version;bool operator>(const Task& rhs) const {return ttl > rhs.ttl;}};std::shared_ptr<Node> head, tail;int capacity;std::unordered_map<int, std::shared_ptr<Node>> mp;bool stop;std::thread worker;std::recursive_mutex mutex;std::condition_variable_any cv;std::priority_queue<Task, std::vector<Task>, std::greater<Task>> que;void detach(std::shared_ptr<Node>& cur) {auto prev = cur->prev.lock();prev->next = cur->next;cur->next->prev = prev;cur->next = nullptr;cur->prev.reset();}void insert_after(std::shared_ptr<Node>& prev, std::shared_ptr<Node>& cur) {cur->next = prev->next;cur->prev = prev;prev->next->prev = cur;prev->next = cur;}bool check_key(int key) {return mp.count(key) && (mp[key]->ttl == steady_clock::time_point{} || steady_clock::now() < mp[key]->ttl);}void run() {while (true) {std::unique_lock<std::recursive_mutex> lock(mutex);cv.wait(lock, [this]{ return stop || !que.empty(); });if (stop) break;while (!que.empty() && que.top().ttl < steady_clock::now()) {const auto [_, key, version] = que.top();que.pop();if (mp.count(key) && mp[key]->version == version) {auto cur = mp[key];mp.erase(key);detach(cur);}}if (!que.empty()) {cv.wait_until(lock, que.top().ttl);}}}public:LRUCache(int capacity) {this->capacity = capacity;stop = false;worker = std::thread(&LRUCache::run, this);head = std::make_shared<Node>();tail = std::make_shared<Node>();head->next = tail;tail->prev = head;}~LRUCache() {{std::lock_guard<std::recursive_mutex> lock(mutex);stop = true;cv.notify_one();}if (worker.joinable()) {worker.join();}}int get(int key) {std::lock_guard<std::recursive_mutex> lock(mutex);if (check_key(key)) {auto cur = mp[key];detach(cur);insert_after(head, cur);return cur->value;}return -1;}void put(int key, int value) {std::lock_guard<std::recursive_mutex> lock(mutex);if (mp.count(key)) {auto cur = mp[key];detach(cur);insert_after(head, cur);cur->value = value;cur->version++;cur->ttl = {};} else if (mp.size() < capacity) {auto cur = std::make_shared<Node>(key, value, 0);mp[key] = cur;insert_after(head, cur);} else {auto cur = tail->prev.lock();detach(cur);insert_after(head, cur);mp.erase(cur->key);mp[key] = cur;cur->key = key; cur->value = value;cur->ttl = {}; cur->version = 0;}cv.notify_one();}void put(int key, int value, steady_clock::duration ttl) {std::lock_guard<std::recursive_mutex> lock(mutex);put(key, value);auto cur = mp[key];cur->ttl = steady_clock::now() + ttl;que.push({cur->ttl, key, cur->version});cv.notify_one();}
};
http://www.xdnf.cn/news/15719.html

相关文章:

  • 《通信原理》学习笔记——第四章
  • IDEA 中 Maven 配置:当前项目与新项目的统一设置方法
  • final 使用
  • oracle 11.2.0.4 RAC下执行root.sh脚本报错
  • leetcode2_135.分发糖果
  • ollma dify 搭建合同审查助手
  • 【Python】一些PEP提案(三):with 语句、yield from、虚拟环境
  • MySQL中的索引和事务
  • vue2 面试题及详细答案150道(81 - 90)
  • 解锁 Java 并发编程的奥秘:《Java 并发编程之美》中的技术亮点与难题攻克
  • FastAdmin后台登录地址变更原理与手动修改方法-后台入口机制原理解析-优雅草卓伊凡
  • 【计算机网络】MAC地址与IP地址:网络通信的双重身份标识
  • TCP通讯开发注意事项及常见问题解析
  • 接口测试的原则、用例与流程详解
  • 百度权重提升技巧分析:从底层逻辑到实战策略
  • 某邮生活旋转验证码识别
  • 函数返回值问题,以及返回值的使用问题(c/c++)
  • 4G模块 A7680发送中文短信到手机
  • 2-大语言模型—理论基础:详解Transformer架构的实现(2)
  • 雾化技术赋能 全鼎如何打造软磁材料护城河
  • 最小生成树算法详解
  • 基于单片机红外感应智能卫生间系统仿真论文
  • 开源Docmost知识库管理工具
  • Web开发 02
  • MariaDB 10.4.34 安装配置文档(Windows 版)
  • ChatGPT Agent:统一端到端Agentic模型的技术革新与行业影响
  • 深度学习模型开发部署全流程:以YOLOv11目标检测任务为例
  • 【CF】⭐Day104——Codeforces Round 840 (Div. 2) CE (思维 + 分类讨论 | 思维 + 图论 + DP)
  • hadoop(服务器伪分布式搭建)
  • 一文讲清楚React性能优化