在看leveldb实现过程中发现小和尚的藏经阁里提到 LRUCache,翻书,发现是内存的普遍实现。
Cache有种实现:hit一次就让计数器+1,这样需要覆盖,就找count最少的。每次都需要轮询,效率低。所以LRUCache就出来了
C++实现 这里已经有很好的实现了 如何用C++实现一个LRU Cache
我下面就是抄了一遍。是的,抄了一遍,关键要记住
//A simple LRUCache demo
//double linked list + hashmap
#include <iostream>
#include <cassert>
#include <vector>
#include <ext/hash_map>
using namespace std;
using namespace __gnu_cxx;
template< class K, class T>
struct Node{
K key;
T value;
Node *prev,*next;
};
template< class K, class T>
class LRUCache {
public:
LRUCache(size_t size){
entries_ = new Node<K,T>[size];
for(int i=0;i<size;i++)
free_entries_.push_back(entries_+i);
head_ = new Node<K,T>;
tail_ = new Node<K,T>;
head_->prev = NULL;
head_->next = tail_;
tail_->prev = head_;
tail_->next = NULL;
}
~LRUCache(){
delete head_;
delete tail_;
delete[] entries_;
}
T Get(K key){
Node<K,T>* node = hashmap_[key];
if(node){
detach(node);
attach(node);
return node->value;
}
else{
return T();
}
}
void Put(K key, T value){
Node<K,T> *node = hashmap_[key];
if(node){//node exist
detach(node);
node->value = value;
attach(node);
}else{
if(free_entries_.empty()){//cache full
node = tail_->prev;
detach(tail_->prev);
hashmap_.erase(node->key);
}else{
//cache available
node = free_entries_.back();
free_entries_.pop_back();
}
node->key = key;
node->value = value;
hashmap_[key] = node;
attach(node);
}
}
private:
Node<K,T> *head_,*tail_;
Node<K,T> *entries_;
hash_map<K, Node<K,T>* > hashmap_;
vector<Node<K,T>* > free_entries_;
void detach(Node<K,T>* node){
node->next->prev = node->prev;
node->prev->next = node->next;
}
void attach(Node<K,T>* node){
node->prev = head_;
node->next = head_->next;
head_->next = node;
head_->next->prev = node;
}
};
int main(int argc, char* argv[]){
hash_map<int,int> map;
map[9]= 999;
cout<<map[9]<<endl;
cout<<map[10]<<endl;
LRUCache<int,string> lruCache(100);
lruCache.Put(1,"hello");
cout<<lruCache.Get(1)<<endl;
if(lruCache.Get(2) == ""){
cout<<"Put 2!"<<endl;
lruCache.Put(2,"world");
}
cout<<lruCache.Get(2)<<endl;
return 0;
}