使用STL实现LRU缓存

仿照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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值