Generic cache of objects

前端 未结 3 1310
日久生厌
日久生厌 2021-01-11 14:16

Does anyone know any implementation of a templated cache of objects?

  • You use a key to find object (the same as in std::map<>)
  • You specify a maximum
3条回答
  •  猫巷女王i
    2021-01-11 14:32

    Ive put together a relatively simple LRU cache built from a map and a linked list:

    template::iterator>>
    class LRUCache
    {
        size_t maxSize;
        Map data;
        std::list usageOrder;
        std::function)> onEject = [](std::pair x){};
    
        void moveToFront(typename std::list::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(itr->first, *(itr->second)));
                data.erase(usageOrder.back());
                usageOrder.erase(--usageOrder.end());
            }
        }
    
    public:
        typedef std::pair 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
        V& getOrCompute(const K& k)
        {
            if(!data.contains(k)) insert(value_type(k, Compute()));
            return(at(k));
        }
    
        void setOnEject(decltype(onEject) f)
        {
            onEject = f;
        }
    };
    

    Which I believe meets your criteria. Anything need to be added, or changed?

提交回复
热议问题