LRU Cache

来源:互联网 发布:百会云计算 编辑:程序博客网 时间:2024/05/15 05:00

设计一个LRU cache, 如果想时间复杂度O(1), 则必须用到hash.


这里有一个使用STL实现的lru cache 模板类源码
LRU cache implementation in C++

http://timday.bitbucket.org/lru.html?1364610172

下面是自己随便写的一个lru测试程序, 逻辑验证正确.

#include <stdio.h>#include <stdlib.h>#include <string>#include <arpa/inet.h>#include <sstream>#include <vector>#include <list>#include <map>#include <ext/hash_map>#include <list>#include <unistd.h> // for usleepusing namespace std;using namespace __gnu_cxx;#ifndef foreach#define foreach(container,it) \            for(typeof((container).begin()) it = (container).begin();it!=(container).end();++it)#endifstruct DataValue{    string ss;    int appid;    string Info()    {        char buf[128];        snprintf(buf, sizeof(buf), "[ss:%s, appid:%d]", ss.c_str(), appid);        return buf;    }};int MakeValue(int appid, DataValue& v){    v.ss = "hello";    v.appid = appid;    return 0;}typedef int (*make_value_pt)(int, DataValue&);class CLRU{public:    CLRU(make_value_pt fn, int cache_size):        _fn_make_value(fn),        CACHE_SIZE(cache_size)    {}public:    void get(int appid, DataValue& dv)    {        // 如果key已经存在, 把key移动到队tail        if (key_map.find(appid) != key_map.end())        {            key_lru_list.splice(key_lru_list.end(), key_lru_list, key_map[appid].second);            dv = key_map[appid].first;        }        // if not exiest        else        {            // if cash size is full, evict            if (key_lru_list.size() >= (unsigned int)CACHE_SIZE)            {                key_map.erase(key_lru_list.front());                key_lru_list.erase(key_lru_list.begin());            }            // make a value for key            _fn_make_value(appid, dv);            // insert            key_lru_list.push_back(appid);            key_map[appid] = pair<DataValue, list<int>::iterator>(dv, --key_lru_list.end());        }    }    // just for debug    void output()    {        foreach(key_lru_list, it)        {            int appid = *it;            printf("appid:%u, dv:%s\n",                     appid, key_map[appid].first.Info().c_str());        }    }public:    list<int>           key_lru_list;    hash_map<int, pair<DataValue, list<int>::iterator> > key_map;    make_value_pt       _fn_make_value;    int                 CACHE_SIZE;};int main(){    CLRU lru(MakeValue, 3);    DataValue dv;    lru.get(1, dv);    printf("dv:%s\n", dv.Info().c_str());    lru.output();    printf("----------\n");    lru.get(2, dv);    printf("dv:%s\n", dv.Info().c_str());    lru.output();    printf("----------\n");       lru.get(3, dv);    printf("dv:%s\n", dv.Info().c_str());    lru.output();    printf("----------\n");    lru.get(4, dv);    printf("dv:%s\n", dv.Info().c_str());    lru.output();    printf("----------\n");    lru.get(3, dv);    printf("dv:%s\n", dv.Info().c_str());    lru.output();    printf("----------\n");    return 0;}
输出如下:
dv:[ss:hello, appid:1]appid:1, dv:[ss:hello, appid:1]----------dv:[ss:hello, appid:2]appid:1, dv:[ss:hello, appid:1]appid:2, dv:[ss:hello, appid:2]----------dv:[ss:hello, appid:3]appid:1, dv:[ss:hello, appid:1]appid:2, dv:[ss:hello, appid:2]appid:3, dv:[ss:hello, appid:3]----------dv:[ss:hello, appid:4]appid:2, dv:[ss:hello, appid:2]appid:3, dv:[ss:hello, appid:3]appid:4, dv:[ss:hello, appid:4]----------dv:[ss:hello, appid:3]appid:2, dv:[ss:hello, appid:2]appid:4, dv:[ss:hello, appid:4]appid:3, dv:[ss:hello, appid:3]----------


原创粉丝点击