lru缓存linux,linux c/c++ 后台开发常用组件之: 高性能LRU本地缓存

缓存在后台开发中是经常使用的,通常有通用的缓存服务,开源的有memcache, redis,  但是在数据量不是特别大,性能要求极高的情况,以及减少搭建和维护专门的缓存服务的成本,本地缓存具有很好的性能以及减少运维成本,本地缓存可以显著的减少网络开销,带来更高的性能,还可以避免缓存服务单点问题 ,下面是自己封装的一个基于LRU缓存淘汰算法的多线程安全LRU缓存组件,已经在项目中使用,性能比memcache高出很多。

/***************************************

function: local lru cache

author: liuyi

date: 2015.10.24

version: 1.0

****************************************/

#ifndef LRU_CACHE_H

#define LRU_CACHE_H

#include

#include

#include

#include

#include

using namespace std;

template

class lru_cache

{

public:

struct cache_data

{

time_t begin_time;

time_t update_time;

int expire_time;

int count;

T2 data;

};

lru_cache()

{

m_max_size = 0;

m_avg_expire_time = 0;

m_mutex = NULL;

m_cache_map = NULL;

}

~lru_cache()

{

m_max_size = 0;

if(NULL != m_cache_map)

{

delete m_cache_map;

m_cache_map = NULL;

}

if(m_mutex != NULL)

{

pthread_mutex_destroy(m_mutex);

}

}

bool init(int max_cache_size)

{

m_mutex = new pthread_mutex_t;

m_cache_map = new map;

m_max_size = max_cache_size;

pthread_t id;

pthread_mutex_init(m_mutex, NULL);

pthread_create(&id, NULL, expire_thread, this);

return true;

}

bool get(const T1& key, T2& data)

{

pthread_mutex_lock(m_mutex);

typename map::iterator it = m_cache_map->find(key);

if(it == m_cache_map->end())

{

pthread_mutex_unlock(m_mutex);

return false;

}

data = it->second.data;

it->second.count++;

it->second.update_time = time(NULL);

pthread_mutex_unlock(m_mutex);

return true;

}

bool set(const T1& key, const T2& data, const int& expire_time = -1)

{

cache_data new_data;

new_data.count = 0;

new_data.expire_time = expire_time;

new_data.begin_time = time(NULL);

new_data.update_time = new_data.begin_time;

new_data.data = data;

pthread_mutex_lock(m_mutex);

if(m_cache_map->size() >= m_max_size)

{

pthread_mutex_unlock(m_mutex);

lru_remove();

pthread_mutex_lock(m_mutex);

}

m_cache_map->insert(pair(key, new_data));

pthread_mutex_unlock(m_mutex);

return true;

}

bool remove(const T1& key)

{

pthread_mutex_lock(m_mutex);

if(m_cache_map->find(key) != m_cache_map->end())

{

m_cache_map->erase(key);

pthread_mutex_unlock(m_mutex);

return true;

}

pthread_mutex_unlock(m_mutex);

return false;

}

bool lru_remove()

{

pthread_mutex_lock(m_mutex);

typename map::iterator lru_it = m_cache_map->begin();

typename map::iterator it = m_cache_map->begin();

if(it == m_cache_map->end())

{

pthread_mutex_unlock(m_mutex);

return false;

}

size_t weight = it->second.count + it->second.update_time;

for(++it; it != m_cache_map->end(); ++it)

{

if(it->second.count + it->second.update_time < weight)//lru

{

weight = it->second.count + it->second.update_time;

lru_it = it;

}

}

m_cache_map->erase(lru_it);

pthread_mutex_unlock(m_mutex);

return true;

}

int lru_expire()

{

int count = 0;

pthread_mutex_lock(m_mutex);

long long sum = 0;

for(typename map::iterator it = m_cache_map->begin();

it != m_cache_map->end();)

{

sum += it->second.expire_time;

if(it->second.expire_time >= 0

&& time(NULL) - it->second.update_time >= it->second.expire_time)

{

m_cache_map->erase(it++);

++count;

}

else

{

++it;

}

}

if(!m_cache_map->empty())

{

m_avg_expire_time = sum / m_cache_map->size();

}

pthread_mutex_unlock(m_mutex);

return count;

}

int get_avg_expire_time()const

{

pthread_mutex_lock(m_mutex);

int avg_expire_time = m_avg_expire_time;

pthread_mutex_unlock(m_mutex);

return avg_expire_time;

}

private:

static void* expire_thread(void *args)

{

lru_cache *p_instance = (lru_cache *)args;

for(;;)

{

sleep(abs(p_instance->get_avg_expire_time()/2));

p_instance->lru_expire();

}

return NULL;

}

private:

int m_max_size;

int m_avg_expire_time;

map *m_cache_map;

pthread_mutex_t *m_mutex;

};

#endif

 
 

#include "lru_cache.h"

int main()

{

lru_cache test_cache;

test_cache.init(2);

test_cache.set(1, 1);

int a = 0;

if(test_cache.get(1, a))

{

cout<

}

else

{

cout<

}

if(test_cache.remove(1))

{

cout<

}

if(test_cache.get(1, a))

{

cout<

}

else

{

cout<

}

test_cache.set(1, 1, 2);

sleep(3);

if(test_cache.get(1, a))

{

cout<

}

else

{

cout<

}

test_cache.set(1, 1, 3);

test_cache.set(2, 2, 3);

test_cache.get(2, a);

test_cache.get(2, a);

test_cache.get(2, a);

test_cache.set(3, 3, 3);

test_cache.set(4, 4, 3);

test_cache.set(5, 5, 3);

for(int i = 1; i < 6; i++)

{

if(test_cache.get(i, a))

cout<

}

for(;;)

{

sleep(1);

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值