对象的通用缓存

时间:2008-09-23 18:40:31

标签: c++ stl boost

有没有人知道对象的模板化缓存的任何实现?

  • 您使用密钥查找对象(与std :: map<>中相同)
  • 您可以指定可以同时位于缓存中的最大对象数
  • 有创建缓存中找不到的对象的工具
  • 有一些设施可以知道何时从缓存中删除对象

例如:

typedef cache<int, MyObj*> MyCache;
MyCache oCache;
oCache.SetSize(1);
oCache.Insert(make_pair(1, new MyObj());
oCache.Touch(1);
MyObj* oldObj = oCache.Delete(1);

...

它可以像LRU或MRU缓存一样简单。

欢迎任何建议!

尼克

3 个答案:

答案 0 :(得分:2)

您可以使用Boost.MultiIndex库。 实现MRU cache很容易。

答案 1 :(得分:1)

我把一个相对简单的LRU缓存放在一起,它是根据地图和链表建立的:

template<typename K, typename V, typename Map = std::unordered_map<K, typename std::list<K>::iterator>>
class LRUCache
{
    size_t maxSize;
    Map data;
    std::list<K> usageOrder;
    std::function<void(std::pair<K, V>)> onEject = [](std::pair<K, V> x){};

    void moveToFront(typename std::list<K>::iterator itr)
    {
        if(itr != usageOrder.begin())
            usageOrder.splice(usageOrder.begin(), usageOrder, itr);
    }


    void trimToSize()
    {
        while(data.size() > maxSize)
        {
            auto itr = data.find(usageOrder.back());

            onEject(std::pair<K, V>(itr->first, *(itr->second)));
            data.erase(usageOrder.back());
            usageOrder.erase(--usageOrder.end());
        }
    }

public:
    typedef std::pair<const K, V> value_type;
    typedef K key_type;
    typedef V mapped_type;


    LRUCache(size_t maxEntries) : maxSize(maxEntries)
    {
        data.reserve(maxEntries);
    }

    size_t size() const
    {
        return data.size();
    }

    void insert(const value_type& v)
    {
        usageOrder.push_front(v.first);
        data.insert(typename Map::value_type(v.first, usageOrder.begin()));

        trimToSize();
    }

    bool contains(const K& k) const
    {
        return data.count(k) != 0;
    }

    V& at(const K& k)
    {
        auto itr = data.at(k);
        moveToFront(itr);
        return *itr;
    }


    void setMaxEntries(size_t maxEntries)
    {
        maxSize = maxEntries;
        trimToSize();
    }

    void touch(const K& k)
    {
        at(k);
    }

    template<typename Compute>
    V& getOrCompute(const K& k)
    {
        if(!data.contains(k)) insert(value_type(k, Compute()));
        return(at(k));
    }

    void setOnEject(decltype(onEject) f)
    {
        onEject = f;
    }
};

我认为符合您的标准。是否需要添加或更改任何内容?

答案 2 :(得分:-5)

在一个应用程序中,我很难想象它会加速/提升性能来存储显然可以重新创建的对象(臀部:因为它们可以在缓存顶部时被自动丢弃)。 sw缓存需要通过关联性代码获取内存,肯定比内存分配和构造函数运行慢(主要是内存初始化)。

除了手动用户配置以避免分页机制(正好提升性能,顺便说一句),大多数操作系统“缓存”磁盘上的内存......它是“分页”,一种“高成本缓存” “,因为没有任何东西被扔掉,而且它是由特定的HW完成的,一个称为内存管理单元的子处理单元......

总体而言,缓存代码会在冗余的同时减慢进程。