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 ...
随机推荐
- SQLServer的数据存储结构01 文件与文件组
在SQLServer中,每当新建一个数据库时,则会有一组相应的SQLServer文件被创建,这些单独的SQLServer文件构成的总体称为文件组. 一个数据库对应着一个文件组,在这个文件组里,会包括三 ...
- mysql复制一列到另一列
mysql复制一列到另一列 UPDATE 表名 SET B列名=A列名 需求:把一个表某个字段内容复制到另一张表的某个字段. 实现sql语句1: 复制代码代码如下: UPDATE file_man ...
- C++输入cout与输出cin
输入和输出并不是C++语言中的正式组成成分.C和C++本身都没有为输入和输出提供专门的语句结构.输入输出不是由C++本身定义的,而是在编译系统提供的I/O库中定义的.C++的输出和输入是用" ...
- HashSet和HashMap的区别
HashSet和HashMap的区别.Java的HashSet类是由哈希表支持.它不保证 set 的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用 null 元素.HashSet类为基本操作提供 ...
- MAC OSX环境下cordova+Ionic的安装配置
一.简介 1.Ionic是什么 IONIC 是目前最有潜力的一款 HTML5 手机应用开发框架.通过 SASS 构建应用程序,它提供了很多 UI 组件来帮助开发者开发强大的应用. 它使用 JavaSc ...
- 数据库大作业--由python+flask
这个是项目一来是数据库大作业,另一方面也算是再对falsk和python熟悉下,好久不用会忘很快. 界面相比上一个项目好看很多,不过因为时间紧加上只有我一个人写,所以有很多地方逻辑写的比较繁琐,如果是 ...
- 对于Python中RawString的理解
总结 1.'''作用: 可以表示 "多行注释" ."多行字符串" ."其内的单双引号不转义" 2.r 代表的意思是: raw 3.r 只对其 ...
- 新春测 kinect motor
大年30,祝所有开发伙伴新春快乐. 天天FQ, 叹国内学习成本太高 看到一篇台湾 kinect 电机控制, 赞 using Microsoft.Kinect; using System; using ...
- C++ void*的使用
void*类型可以存储任何类型的指针,使用的时候强制转化成对应类型的指针便可. #include <iostream> #include <vector> using name ...
- Y Combinator
常见的例子 阶乘函数: fact = (a) -> if a > 0 then a * fact(a - 1) else 1 问题的提出 如上,在fact函数中调用了fact本身,无法使用 ...