LRUCache
2014-01-21 10:37
344 查看
#include <stdexcept>
#include <list>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
typedef struct vkt
{
int v;
int k;
unsigned int t;
}vkt_t, *vkt_p;
inline bool time_comp(const vkt_p& l, const vkt_p& r)
{
return l->t < r->t;
}
typedef std::map<int, vkt_p> kvtk_map;
typedef std::map<int, int> tk_map;
class LRUCache
{
private:
const int _capacity;
std::vector<vkt_p> vkt_buf;
vkt_p ori_buf;
kvtk_map kvtk;
tk_map tk;
const unsigned int max_time;
unsigned int guard;
protected:
vkt_p new_vkt(void)
{
if (vkt_buf.empty())
return NULL;
vkt_p p = vkt_buf.back();
vkt_buf.pop_back();
return p;
}
void del_vkt(vkt_p p)
{
vkt_buf.push_back(p);
}
void adjust_time()
{
if (guard >= max_time)
{
tk.clear();
std::list<vkt_p> lv;
for (kvtk_map::const_iterator iter = kvtk.begin(); iter != kvtk.end(); ++iter)
{
lv.push_back(iter->second);
}
lv.sort(time_comp);
int i = 0;
for (kvtk_map::const_iterator iter = kvtk.begin(); iter != kvtk.end(); ++iter)
{
iter->second->t = i++;
}
guard = i;
for (std::list<vkt_p>::const_iterator iter = lv.begin(); iter != lv.end(); ++iter)
{
tk.insert(std::make_pair((*iter)->t, (*iter)->k));
}
}
}
public:
LRUCache(int capacity) : _capacity(capacity + 1), max_time(~0), guard(0)
{
if (capacity <= 0)
throw std::invalid_argument("capacity must > 0");
ori_buf = new vkt_t[_capacity];
vkt_buf.reserve(_capacity);
for (int i = 0; i < _capacity; ++i)
{
vkt_buf.push_back(ori_buf + i);
}
}
~LRUCache() { delete[] ori_buf; ori_buf = NULL; }
int get(int key)
{
kvtk_map::iterator iter = kvtk.find(key);
if (iter == kvtk.end())
return -1;
tk_map::iterator tkiter = tk.find(iter->second->t);
if (tkiter != tk.end())
tk.erase(tkiter);
iter->second->t = guard++;
int v = iter->second->v;
tk.insert(std::make_pair(iter->second->t, key));
adjust_time();
return v;
}
void set(int key, int value)
{
kvtk_map::iterator iter = kvtk.find(key);
if (iter == kvtk.end())
{
vkt_p p = new_vkt();
if (p != NULL)
{
p->v = value; p->k = key; p->t = guard;
iter = kvtk.insert(std::make_pair(key, p)).first;
}
}
if (iter != kvtk.end())
{
tk_map::iterator tkiter = tk.find(iter->second->t);
if (tkiter != tk.end())
tk.erase(tkiter);
iter->second->t = guard++;
iter->second->v = value;
tk.insert(std::make_pair(iter->second->t, key));
}
if (kvtk.size() == _capacity)
{
tk_map::iterator tkiter = tk.begin();
if (tkiter != tk.end())
{
int k = tkiter->second;
tk.erase(tkiter);
kvtk_map::iterator iter = kvtk.find(k);
if (iter != kvtk.end())
{
del_vkt(iter->second);
kvtk.erase(iter);
}
}
}
adjust_time();
}
int size(void) const { return (int)kvtk.size(); }
int old_val(void) const
{
tk_map::const_iterator tkit = tk.begin();
if (tkit != tk.end())
{
kvtk_map::const_iterator kvtkit = kvtk.find(tkit->second);
if (kvtkit != kvtk.end())
return kvtkit->second->v;
}
return -1;
}
int new_val(void) const
{
tk_map::const_reverse_iterator tkit = tk.rbegin();
if (tkit != tk.rend())
{
kvtk_map::const_iterator kvtkit = kvtk.find(tkit->second);
if (kvtkit != kvtk.end())
return kvtkit->second->v;
}
return -1;
}
};
#include <cassert>
int main(int argc, char* argv[])
{
LRUCache lru(10);
assert(-1 == lru.get(0));
for (int i = 0; i < 0xFF0; ++i)
{
lru.set(i, i);
}
assert(lru.size() == 10);
for (int i = 0; i < 100; ++i)
{
lru.set(i, i);
}
assert(lru.size() == 10);
assert(lru.get(5) == -1);
assert(lru.get(95) == 95);
assert(lru.get(100) == -1);
assert(lru.new_val() == 95);
assert(lru.old_val() == 90);
lru.set(4, 10);
assert(lru.new_val() == 10);
assert(lru.old_val() == 91);
assert(lru.get(0) == -1);
lru.set(0, 0);
assert(lru.new_val() == 0);
assert(lru.old_val() == 92);
return 0;
}
#include <list>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
typedef struct vkt
{
int v;
int k;
unsigned int t;
}vkt_t, *vkt_p;
inline bool time_comp(const vkt_p& l, const vkt_p& r)
{
return l->t < r->t;
}
typedef std::map<int, vkt_p> kvtk_map;
typedef std::map<int, int> tk_map;
class LRUCache
{
private:
const int _capacity;
std::vector<vkt_p> vkt_buf;
vkt_p ori_buf;
kvtk_map kvtk;
tk_map tk;
const unsigned int max_time;
unsigned int guard;
protected:
vkt_p new_vkt(void)
{
if (vkt_buf.empty())
return NULL;
vkt_p p = vkt_buf.back();
vkt_buf.pop_back();
return p;
}
void del_vkt(vkt_p p)
{
vkt_buf.push_back(p);
}
void adjust_time()
{
if (guard >= max_time)
{
tk.clear();
std::list<vkt_p> lv;
for (kvtk_map::const_iterator iter = kvtk.begin(); iter != kvtk.end(); ++iter)
{
lv.push_back(iter->second);
}
lv.sort(time_comp);
int i = 0;
for (kvtk_map::const_iterator iter = kvtk.begin(); iter != kvtk.end(); ++iter)
{
iter->second->t = i++;
}
guard = i;
for (std::list<vkt_p>::const_iterator iter = lv.begin(); iter != lv.end(); ++iter)
{
tk.insert(std::make_pair((*iter)->t, (*iter)->k));
}
}
}
public:
LRUCache(int capacity) : _capacity(capacity + 1), max_time(~0), guard(0)
{
if (capacity <= 0)
throw std::invalid_argument("capacity must > 0");
ori_buf = new vkt_t[_capacity];
vkt_buf.reserve(_capacity);
for (int i = 0; i < _capacity; ++i)
{
vkt_buf.push_back(ori_buf + i);
}
}
~LRUCache() { delete[] ori_buf; ori_buf = NULL; }
int get(int key)
{
kvtk_map::iterator iter = kvtk.find(key);
if (iter == kvtk.end())
return -1;
tk_map::iterator tkiter = tk.find(iter->second->t);
if (tkiter != tk.end())
tk.erase(tkiter);
iter->second->t = guard++;
int v = iter->second->v;
tk.insert(std::make_pair(iter->second->t, key));
adjust_time();
return v;
}
void set(int key, int value)
{
kvtk_map::iterator iter = kvtk.find(key);
if (iter == kvtk.end())
{
vkt_p p = new_vkt();
if (p != NULL)
{
p->v = value; p->k = key; p->t = guard;
iter = kvtk.insert(std::make_pair(key, p)).first;
}
}
if (iter != kvtk.end())
{
tk_map::iterator tkiter = tk.find(iter->second->t);
if (tkiter != tk.end())
tk.erase(tkiter);
iter->second->t = guard++;
iter->second->v = value;
tk.insert(std::make_pair(iter->second->t, key));
}
if (kvtk.size() == _capacity)
{
tk_map::iterator tkiter = tk.begin();
if (tkiter != tk.end())
{
int k = tkiter->second;
tk.erase(tkiter);
kvtk_map::iterator iter = kvtk.find(k);
if (iter != kvtk.end())
{
del_vkt(iter->second);
kvtk.erase(iter);
}
}
}
adjust_time();
}
int size(void) const { return (int)kvtk.size(); }
int old_val(void) const
{
tk_map::const_iterator tkit = tk.begin();
if (tkit != tk.end())
{
kvtk_map::const_iterator kvtkit = kvtk.find(tkit->second);
if (kvtkit != kvtk.end())
return kvtkit->second->v;
}
return -1;
}
int new_val(void) const
{
tk_map::const_reverse_iterator tkit = tk.rbegin();
if (tkit != tk.rend())
{
kvtk_map::const_iterator kvtkit = kvtk.find(tkit->second);
if (kvtkit != kvtk.end())
return kvtkit->second->v;
}
return -1;
}
};
#include <cassert>
int main(int argc, char* argv[])
{
LRUCache lru(10);
assert(-1 == lru.get(0));
for (int i = 0; i < 0xFF0; ++i)
{
lru.set(i, i);
}
assert(lru.size() == 10);
for (int i = 0; i < 100; ++i)
{
lru.set(i, i);
}
assert(lru.size() == 10);
assert(lru.get(5) == -1);
assert(lru.get(95) == 95);
assert(lru.get(100) == -1);
assert(lru.new_val() == 95);
assert(lru.old_val() == 90);
lru.set(4, 10);
assert(lru.new_val() == 10);
assert(lru.old_val() == 91);
assert(lru.get(0) == -1);
lru.set(0, 0);
assert(lru.new_val() == 0);
assert(lru.old_val() == 92);
return 0;
}
相关文章推荐
- 使用memcached缓存 替代solr中的LRUCache缓存
- Android4.0中DiskLruCache和LruCache
- LRUCache
- 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅
- Android使用 LruCache 缓存图片
- 图片缓存LruCache 高效加载图片 学习笔记 + 开源项目:DiskLruCache
- leetcode-LRUCache的解
- 图片缓存之内存缓存技术LruCache,软引用
- LRUCache和FastLRUCache实现分析
- 利用LruCache加载网络图片实现图片瀑布流效果(改进版)
- 【源码】LruCache源码剖析
- 【android】照片墙完整版,完美结合LruCache和DiskLruCache
- android本地图片加载器,LruCache缓存机制
- android LruCache的使用 (本地缓存+内存缓存)
- 利用LruCache和DiskLruCache加载网络图片实现图片瀑布流效果(升级版)
- lruCache使用用于图片缓存
- Android 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅
- (4.4.1.4)图片缓存之内存缓存技术LruCache,软引用
- android网络相册(带磁盘缓存DiskLruCache 和内存缓存LruCache)
- Android使用 LruCache 缓存图片