leveldb -- 2 [LRUCache C++ 實現]

在看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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章