LRU Cache

来源:互联网 发布:禁止ip访问http linux 编辑:程序博客网 时间:2024/05/29 17:42

怎么去想:

一般的cache就是一个map,LRU性质需要维护least recently used。当一个key被访问,这个key就处于离被移出cache最远的位置,下一次又有一个key被访问,之前的key就变为离被移除cache次远的位置,这里面就有队列的性质,队列的尾就是least recently used,队头就是最久未被访问的。只不过一般队列只是增加新的,cache key的队列可以把队列里任意位置的一个元素移到队尾。

当访问一个key时,需要立刻定位到LRU队列对应的位置,所以需要一个map 来关联key和 key在LRU中的位置,为了方便删除(不用找前继结点)队列用双向链表。


进一步的,因为双链表节点的移动只是修改指针,节点大小无所谓,所以LRU队列可以不仅放key,而是key和数据都放。这样就不需要单独的map放数据,而是只是一个作为locator的 map 和 一个节点包含key和数据的双链表就够了,locator定位到队列的位置,数据也就定位到了。

class LRUCache{public:    LRUCache(int capacity) {        this->capacity = capacity;    }        int get(int key) {        auto it = m.find(key);        if(it==m.end()) return -1;        int ret = it->second->second;        l.splice(l.end(), l, it->second);        it->second=prev(l.end());        return ret;    }        void set(int key, int value) {        auto it = m.find(key);        if(it!=m.end()){            it->second->second = value;            l.splice(l.end(), l, it->second);        }else{            if(l.size()==capacity){                m.erase(l.front().first);                l.pop_front();            }            l.push_back(make_pair(key, value));        }        m[key]=prev(l.end());    }private:    list<pair<int,int>> l;    unordered_map<int,list<pair<int,int>>::iterator> m;    int capacity;};


0 0