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 ...
随机推荐
- PHPStorm技巧篇 -- 观感优化
(1)设置默认显示行号 (2)设置自动换行 (3)去除代码下划线(拼写检测) 优化说明:自动换行和显示行号字面意思很好理解,下划线说明一下,phpstorm默认对代码进行拼写校验,即对于不符合英文单词 ...
- phpstorm取消强制换行
1 取消phpstorm右侧竖线显示 2 取消格式化代码时 自动换行
- VB模拟键盘输入的N种方法
VB模拟键盘输入的N种方法http://bbs.csdn.net/topics/90509805hd378发表于: 2006-12-24 14:35:39用VB模拟键盘事件的N种方法 键盘是我们使用计 ...
- 分组找ID
select t.name1,t.name2,t.zx from (select row_number()over(partition by name1 order by zx desc)rn, te ...
- 【OS】分页和分段
在网上找到了一个比较形象的比喻 打个比方,比如说你去听课,带了一个纸质笔记本做笔记.笔记本有100张纸,课程有语文.数学.英语三门,对于这个笔记本的使用,为了便于以后复习方便,你可以有两种选择. ...
- [WPF]MenuItem右侧空白
<Window> <Grid Background="SteelBlue"> <Grid.ContextMenu> <ContextMen ...
- MySQL DDL 整理
DDL is Data Definition Language statements. Some examples:数据定义语言,用于定义和管理 SQL 数据库中的所有对象的语言 -- 清空表内容 T ...
- ftp put本地文件至ubuntu服务器报错
起因:我想把本地下载的安装包上传至服务器. 由于Mac的ftp图形化客户端还没找着合适的,就想着用命令也是一样的. 但是又进坑了. 下载能够正常运行: ftp> get 2.jpg /Users ...
- python的string用法
s.strip().lstrip().rstrip(',') S.lower() #小写 S.upper() #大写 S.swapcase() #大小写互换 S.capitalize() #首字母大写 ...
- redhat自定义安装必选
redhat自定义安装必选 1.桌面 ked桌面 x 窗口系统 2.应用程序 编辑器 基于文本的互联网 图形互联网 3.服务器 服务器配置工具 万维网服务器 Windows文件 FTP服务器