最近在看Leveldb源码,里面用到LRU(Least Recently Used)缓存,所以自己动手来实现一下。LRU Cache通常实现方式为Hash Map + Double Linked List,我使用std::map来代替哈希表。

实现代码如下:

#include <iostream>
#include <map>
#include <assert.h> using namespace std; // define double linked list node
template<class K, class V>
struct Node{
K key;
V value;
Node *pre_node;
Node *nxt_node;
Node() : key(K()), value(V()), pre_node(0), nxt_node(0){}
}; // define LRU cache.
template<class K, class V>
class LRUCache{
public:
typedef Node<K, V> CacheNode;
typedef map<K, CacheNode*> HashTable; LRUCache(const int size) : capacity(size), count(0), head(0), tail(0){
head = new CacheNode;
tail = new CacheNode;
head->nxt_node = tail;
tail->pre_node = head;
}
~LRUCache(){
HashTable::iterator itr = key_node_map.begin();
for (itr; itr != key_node_map.end(); ++itr)
delete itr->second;
delete head;
delete tail;
} void put(const K &key, const V &value){
// check if key already exist.
HashTable::const_iterator itr = key_node_map.find(key);
if (itr == key_node_map.end()){
CacheNode *node = new CacheNode;
node->key = key;
node->value = value;
if (count == capacity)
{
CacheNode *tail_node = tail->pre_node;
extricateTheNode(tail_node);
key_node_map.erase(tail_node->key);
delete tail_node;
count--;
} key_node_map[key] = node;
count++;
moveToHead(node);
}
else{
itr->second->value = value;
extricateTheNode(itr->second);
moveToHead(itr->second);
}
} V get(const K &key){
// check if key already exist.
HashTable::const_iterator itr = key_node_map.find(key);
if (itr == key_node_map.end()){
return V();
}
else{
extricateTheNode(itr->second);
moveToHead(itr->second);
return itr->second->value;
}
} void print(){
if (count == 0)
cout << "Empty cache." << endl; cout << "Cache information:" << endl;
cout << " " << "capacity: " << capacity << endl;
cout << " " << "count: " << count << endl;
cout << " " << "map size: " << key_node_map.size() << endl;
cout << " " << "keys: ";
CacheNode *node = head;
while (node->nxt_node != tail)
{
cout << node->nxt_node->key << ",";
node = node->nxt_node;
}
cout << endl;
} private:
void moveToHead(CacheNode *node){
assert(head);
node->pre_node = head;
node->nxt_node = head->nxt_node;
head->nxt_node->pre_node = node;
head->nxt_node = node;
}
void extricateTheNode(CacheNode *node){ // evict the node from the list.
assert(node != head && node != tail);
node->pre_node->nxt_node = node->nxt_node;
node->nxt_node->pre_node = node->pre_node;
} private:
int capacity;
int count;
Node<K, V> *head;
Node<K, V> *tail;
HashTable key_node_map;
}; int main()
{
LRUCache<int, int> my_cache(4); for (int i = 0; i < 20; ++i)
{
int key = rand() % 10 + 1;
int value = key * 2;
cout << "Put[" << key << "," << value << "]>>>" << endl;
my_cache.put(key, value);
my_cache.print();
} for (int i = 0; i < 20; ++i)
{
int key = rand() % 10 + 1;
int value = my_cache.get(key);
cout << "Get value of " << key << ": " << value << ".>>>" << endl;
my_cache.print();
} return 0;
}

LRU Cache实现的更多相关文章

  1. [LeetCode] LRU Cache 最近最少使用页面置换缓存器

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  2. 【leetcode】LRU Cache

    题目简述: Design and implement a data structure for Least Recently Used (LRU) cache. It should support t ...

  3. LeetCode:LRU Cache

    题目大意:设计一个用于LRU cache算法的数据结构. 题目链接.关于LRU的基本知识可参考here 分析:为了保持cache的性能,使查找,插入,删除都有较高的性能,我们使用双向链表(std::l ...

  4. 【leetcode】LRU Cache(hard)★

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  5. [LintCode] LRU Cache 缓存器

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  6. LRU Cache [LeetCode]

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  7. 43. Merge Sorted Array && LRU Cache

    Merge Sorted Array OJ: https://oj.leetcode.com/problems/merge-sorted-array/ Given two sorted integer ...

  8. LeetCode——LRU Cache

    Description: Design and implement a data structure for Least Recently Used (LRU) cache. It should su ...

  9. LRU Cache

    LRU Cache 题目链接:https://oj.leetcode.com/problems/lru-cache/ Design and implement a data structure for ...

随机推荐

  1. 转:Java中abstract和interface的区别

    转自:Java中abstract和interface的区别 abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java ...

  2. mybatis2

    正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Sessio ...

  3. 鼠标hover某个元素时其属性表现Css transition 过渡效果(以宽高属性居中放大为例)

    <!DOCTYPE html> <html> <head> </head> <body id="body"> <! ...

  4. console

    你所不知道的 Console 2016-12-19 ZHANGXIANGLIANG JavaScript 转自 https://segmentfault.com/a/119000000672160 1 ...

  5. java和android的环境变量配置

    Java环境变量配置: 1.新建系统变量 变量名:JAVA_HOME  变量值:F:\JAVA\JDK(自己的JDK文件路径) 2.在系统变量path后面添加:%JAVA_HOME%\bin; And ...

  6. for(String s:v)

    s是遍历后赋值的变量,v是要遍历的list.可以通过以下语句进行测试: List<String> v=new ArrayList(); v.add("one"); v. ...

  7. 关于小组所要做的APP的想法

    关于小组所要做的app,我们敲定下来是做关于在线做题的app,但是,纯粹的做题目的app我认为并没有什么大的吸引力,尤其是拿手机做题.所以,我们考虑准备在以下几个方面做功夫以增加吸引力.第一,我们的题 ...

  8. mysql 存储 emoji报错( Incorrect string value: '\xF0\x9F\x98\x84\xF0\x9F)的解决方案

    1.报错原因: mysql utf-8 编码储存的是 2-3个的字节,而emoji则是4个字节. 2.解决办法: 修改mysql的配置文件,windows下的为my.ini(linux下的为my.cn ...

  9. 用orb-slam2跑RGB-D Example中的TUM Dataset

    链接在此:https://github.com/raulmur/ORB_SLAM2 1.按照要求下载数据集,我下载的是rgbd_dataset_freiburg2_pioneer_360,将其解压到你 ...

  10. JavaScript基础之DOM修改样式

    1.获取或设置元素的内容:3个属性:   1. innerHTML: 获取或设置元素开始标签到结束标签之间的所有HTML代码原文.      何时使用:只要获得完整的html代码原文时      优化 ...