使用STL实现LRU缓存

来源:互联网 发布:百度验证码算法 编辑:程序博客网 时间:2024/05/16 10:53

仿照http://blog.csdn.net/l402398703/article/details/22012551写了一遍LRUCache,自己对LRUCache的理解确实深刻了不少。


cached_map :使用hash_map,便于根据用户提供的Key来找到相应的data

head,tail :表示所有当前已经使用的node节点,这里面的节点和cached_map中是一样的

cached_entries:表示剩余的空闲节点,当新添加元素时,如果cache_entries中还有空闲节点,则取出来,插入到head头部


#include <stdio.h>#include <stdlib.h>#include <string>#include <vector>#include <ext/hash_map>#include <assert.h>using namespace __gnu_cxx;template <class KeyType, class DataType>struct Node{KeyType key;DataType data;struct Node * prev, * next;};template <class KeyType, class DataType>class LRUCache{private:hash_map<KeyType, Node<KeyType, DataType> *> cached_map;Node<KeyType, DataType> * head, * tail;vector<Node<KeyType, DataType> *> cached_entries;Node<KeyType, DataType> * entries; bool pthread_safe;pthread_mutex_t cached_mutex;private:void cache_lock(){if(pthread_safe)pthread_mutex_lock(&cached_mutex); }void cache_unlock(){if(pthread_safe)pthread_mutex_unlock(&cached_mutex); }void attach(Node<KeyType, DataType> * node){node->prev = head;node->next = head->next;head->next->prev = node;head->next = node;}void detach(Node<KeyType, DataType> * node){node->prev->next = node->next;node->next->prev = node->prev;}public:void put(KeyType Key, DataType data);DataType get(KeyType key);LRUCache(int size, bool is_pthread_safe = false){int i = 0;pthread_safe = is_pthread_safe;if(size < 0)size = 1024;entries = new Node<KeyType, DataType>[size];assert(entries != NULL);for(i = 0; i < size; i++)cached_entries.push_back(&entries[i]);head = new Node<KeyType, DataType>();tail = new Node<KeyType, DataType>();assert((head != NULL) && (tail != NULL));head->prev = NULL;tail->next = NULL;head->next = tail;tail->prev = head;if(pthread_safe)pthread_mutex_init(&cached_mutex, NULL); }~LRUCache(){if(pthread_safe)pthread_mutex_destroy(&cached_mutex); delete   head;delete   tail;delete[] entries;}};template <class KeyType, class DataType>void LRUCache<KeyType, DataType>::put(KeyType Key, DataType data){cache_lock();Node<KeyType, DataType> * node = cached_map[Key];if(NULL != node){detach(node);}else{if(cached_entries.empty()){node = tail->prev;detach(node);cached_map.erase(node->key);}else{node = cached_entries.back();cached_entries.pop_back();}}node->data = data;node->key  = Key;cached_map[Key] = node;attach(node);cache_unlock();}template <class KeyType, class DataType>DataType LRUCache<KeyType, DataType>::get(KeyType key){Node<KeyType, DataType> * node = NULL;Node<KeyType, DataType> unused;cache_lock();node = cached_map[key];if(NULL != node){detach(node);attach(node);}else{node = &unused;}cache_unlock();return node->data;}int main(int argc, char * argv[]){int index = 0;LRUCache<int, int> cache(10);for(; index < 999999; index++)cache.put(index, index);return 0;}


0 0
原创粉丝点击