最近最少使用数据结构(LRU)

抛开算法刷题的角度,LRU数据结构可根据访问时间远近自动排序,在有些场景下还是很有用的,如统计用户活跃度,API调用热力图分析,缓存块管理等。下面基于c++模板提供一个通用的LRU类,以供参考。

cpp 复制代码
#include <functional>
#include <list>
#include <unordered_map>
#include <utility>

template<typename Key, typename Val>
class LRUCache {
public:
    using value_deinit_callback = std::function<void(Key, Val)>;
    static void value_release_handle(Key k, Val v)
    {}
    //如果Val是指针类型,可在func中指定指针清理动作
    LRUCache(int capacity, const value_deinit_callback& func = value_release_handle) :
        m_capacity(capacity), m_value_deinit(func)
    {}
    ~LRUCache()
    {
        for (auto pairs : m_cached_list)
        {
            if (m_value_deinit.operator bool())
                m_value_deinit(pairs.first, pairs.second);
        }
        m_hash_table.clear();
        m_cached_list.clear();
    }
    Val get(const Key& key) {
        auto iter = m_hash_table.find(key);
        if (iter == m_hash_table.end())
            return Val{};
        auto& liter = iter->second;
        auto pairs = *liter;
        m_cached_list.erase(liter);
        liter = m_cached_list.insert(m_cached_list.end(), pairs);
        return liter->second;
    }

    void put(Key key, Val val) {
        auto iter = m_hash_table.find(key);
        if (iter != m_hash_table.end())
        {
            auto pairs = *iter->second;
            pairs.second = val;
            m_cached_list.erase(iter->second);
            iter->second = m_cached_list.insert(m_cached_list.end(),pairs);
        }
        else
        {
            if (m_cached_list.size() >= m_capacity)
            {
                auto& pairs = m_cached_list.front();
                auto& fkey = pairs.first;
                auto& fval = pairs.second;
                auto it = m_hash_table.find(fkey);
                if (it != m_hash_table.end())
                {
                    m_value_deinit(fkey, fval);
                    m_hash_table.erase(it);
                }
                m_cached_list.pop_front();
            }
            m_hash_table.insert(std::make_pair(key, m_cached_list.insert(m_cached_list.end(), std::make_pair(key, val))));
        }
    }
private:
    int m_capacity;
    value_deinit_callback m_value_deinit;
    std::unordered_map<Key, typename std::list<std::pair<Key, Val>>::iterator> m_hash_table;
    std::list<std::pair<Key, Val>> m_cached_list;
};
相关推荐
paopaokaka_luck4 分钟前
校园快递小程序(腾讯地图API、二维码识别、Echarts图形化分析)
vue.js·spring boot·后端·小程序·uni-app
用户298698530148 分钟前
C# 使用Spire.XLS快速生成多表格Excel文件
后端
盖世英雄酱5813616 分钟前
国企“高级”程序员写的那些问题代码(六期)
java·后端
嘟爸教编程18 分钟前
C++少儿编程(二十二)—条件结构
开发语言·c++
南囝coding31 分钟前
这个Web新API让任何内容都能画中画!
前端·后端
林太白37 分钟前
VitePress项目工程化应该如何做
前端·后端
霖0041 分钟前
FPGA的PS基础1
数据结构·人工智能·windows·git·算法·fpga开发
字节跳跃者1 小时前
Java 中的 Stream 可以替代 for 循环吗?
java·后端
北执南念1 小时前
如何在 Spring Boot 中设计和返回树形结构的组织和部门信息
java·spring boot·后端
修仙的人2 小时前
【开发环境】 VSCode 快速搭建 Python 项目开发环境
前端·后端·python