LRU Cache实现
最近在看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实现的更多相关文章
- [LeetCode] LRU Cache 最近最少使用页面置换缓存器
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- 【leetcode】LRU Cache
题目简述: Design and implement a data structure for Least Recently Used (LRU) cache. It should support t ...
- LeetCode:LRU Cache
题目大意:设计一个用于LRU cache算法的数据结构. 题目链接.关于LRU的基本知识可参考here 分析:为了保持cache的性能,使查找,插入,删除都有较高的性能,我们使用双向链表(std::l ...
- 【leetcode】LRU Cache(hard)★
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- [LintCode] LRU Cache 缓存器
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- LRU Cache [LeetCode]
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- 43. Merge Sorted Array && LRU Cache
Merge Sorted Array OJ: https://oj.leetcode.com/problems/merge-sorted-array/ Given two sorted integer ...
- LeetCode——LRU Cache
Description: Design and implement a data structure for Least Recently Used (LRU) cache. It should su ...
- LRU Cache
LRU Cache 题目链接:https://oj.leetcode.com/problems/lru-cache/ Design and implement a data structure for ...
随机推荐
- MultipeerConnectivity框架,近场通信的基本使用
Multipeer connectivity是一个使附近设备通过Wi-Fi网络.P2P Wi-Fi以及蓝牙个人局域网进行通信的框架.互相链接的节点可以安全地传递信息.流或是其他文件资源,而不用通过网络 ...
- bootstrap-table填坑之旅<二>事件
接着研究bootstrap-table... ... 这一篇研究bootstrap-table的事件及回调函数 先上一个demo HTML <div class="alert aler ...
- 让Java和MySQL连接起来
Java 连接 MySQL 需要驱动包,可以下载菜鸟教程提供的 jar 包:http://static.runoob.com/download/mysql-connector-java-5.1.39- ...
- Map拷贝 关于对象深拷贝 浅拷贝的问题
问题:map拷贝时发现数据会变化. 高能预警,你看到的下面的栗子是不正确的,后面有正确的一种办法,如果需要看的话的,请看到底,感谢各同学的提醒,已做更正,一定要看到最后 先看例子: ...
- 转!java基础笔记
原博文地址:http://blog.csdn.net/u012152619/article/details/48024345 Java标识符 Java所有的组成部分都需要名字.类名.变量名以及方法名都 ...
- 阿里巴巴、美团等各大互联网公司的 Java类 校招对本科生有什么要求?
转载: 阿里巴巴.美团等各大互联网公司的 Java类 校招对本科生有什么要求?
- js中对象 类 实例的区别 数据类型 创建对象
类是对象的具体细分,实例是类中的一个具体事物. 基本数据类型和 引用数据类型 基本数据类型:numble string undefined null 引用数据类型:对象和函数 对象数据类型又细分为:对 ...
- Python中 "+=" 使用时的注意事项
代码1: >>> l1=range(3) >>> l2=l1 >>> l2+=[4] >>> l1 [0, 1, 2, 4] & ...
- js/jquery 去掉空格.回车.换行
本文转载自 http://hi.baidu.com/niubore/item/426532faab4ddcc50dd1c8f9 Jquery:$("#accuracy").val( ...
- html/css 布局练习3
效果图: