当前位置:编程学习 > wap >>

当C++遇到IOS应用开发---LRUCache缓存

       考虑到缓存实现多数使用单例模式,这里使用C++的模版方式设计了一个Singlton基类,这样以后只要继承该类,子类就会支持单例模式了。其代码如下:
 
[cpp] 
// 
//  SingltonT.h 
// 
 
#ifndef SingltonT_h 
#define SingltonT_h 
#include <iostream> 
#include <tr1/memory> 
using namespace std; 
using namespace std::tr1; 
template <typename T> 
class Singlton { 
public: 
      static T* instance(); 
      ~Singlton() { 
          cout << "destruct singlton" << endl; 
      } 
protected: 
      Singlton(); 
//private: 
protected: 
      static std::tr1::shared_ptr<T> s_instance; 
      //Singlton(); 
}; 
 
template <typename T> 
std::tr1::shared_ptr<T> Singlton<T>::s_instance; 
  
template <typename T> 
Singlton<T>::Singlton() { 
    cout << "construct singlton" << endl; 

  
template <typename T> 
T* Singlton<T>::instance() { 
    if (!s_instance.get()) 
        s_instance.reset(new T); 
    return s_instance.get(); 

 

       另外考虑到在多线程下对static单例对象进行操作,会出现并发访问同步的问题,所以这里使用了读写互斥锁来进行set(设置数据)的同步。如下:
[cpp] 
#ifndef _RWLOCK_H_ 
#define _RWLOCK_H_ 
 
#define LOCK(q) while (__sync_lock_test_and_set(&(q)->lock,1)) {} 
#define UNLOCK(q) __sync_lock_release(&(q)->lock); 
 
struct rwlock { 
    int write; 
    int read; 
}; 
 
static inline void 
rwlock_init(struct rwlock *lock) { 
    lock->write = 0; 
    lock->read = 0; 

 
static inline void 
rwlock_rlock(struct rwlock *lock) { 
    for (;;) {//不断循环,直到对读计数器累加成功 
        while(lock->write) { 
            __sync_synchronize(); 
        } 
        __sync_add_and_fetch(&lock->read,1); 
        if (lock->write) {//当已是写锁时,则去掉读锁记数器 
            __sync_sub_and_fetch(&lock->read,1); 
        } else { 
            break; 
        } 
    } 

 
static inline void 
rwlock_wlock(struct rwlock *lock) { 
    __sync_lock_test_and_set(&lock->write,1); 
    while(lock->read) { 
        //http://blog.itmem.com/?m=201204 
        //http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/Atomic-Builtins.html 
        __sync_synchronize();//很重要,如果去掉,g++ -O3 优化编译后的生成的程序会产生死锁 
    } 

 
static inline void 
rwlock_wunlock(struct rwlock *lock) { 
    __sync_lock_release(&lock->write); 

 
static inline void 
rwlock_runlock(struct rwlock *lock) { 
    __sync_sub_and_fetch(&lock->read,1); 

 

    这里并未使用pthread_mutex_t来设计锁,而是使用了__sync_fetch_and_add指令体系,     当然最终是否如上面链接中作者所说的比pthread_mutex_t性能要高7-8倍,我没测试过,感兴趣的朋友也可以帮助测试一下。

    有了这两个类之后,我又补充了原文作者中所提到了KEY比较方法的定义,同时引入了id来支持object-c的对象缓存,最终代码修改如下:

[cpp] 
#ifndef _MAP_LRU_CACHE_H_ 
#define _MAP_LRU_CACHE_H_ 
 
#include <string.h> 
#include <iostream> 
#include "rwlock.h" 
#include <stdio.h> 
#include <sys/malloc.h> 
using namespace std; 
 
namespace lru_cache { 
    
static const int DEF_CAPACITY = 100000;//默认缓存记录数 
 
typedef unsigned long long virtual_time; 
 
typedef struct _HashKey 

    NSString* key; 
}HashKey; 
    
typedef struct _HashValue 

    id value_; 
    virtual_time access_; 
}HashValue; 
 
//仅针对HashKey比较器 
template <class key_t> 
struct hashkey_compare{ 
    bool operator()(key_t x, key_t y) const{ 
        return x < y; 
    } 
}; 
        
template <> 
struct hashkey_compare<HashKey> 

    bool operator()(HashKey __x, HashKey __y) const{ 
        string x = [__x.key UTF8String]; 
        string y = [__y.key UTF8String]; 
        return x < y; 
    } 
}; 
        
//自定义map类型 
template <typename K, typename V, typename _Compare = hashkey_compare<K>, 
typename _Alloc = std::allocator<std::pair<const K, V> > > 
class  lru_map: public map<K, V, _Compare, _Alloc>{}; 
            
class CLRUCache 

public: 
    
    CLRUCache() : _now(0){ 
        _lru_list = shared_ptr<lru_map<virtual_time, HashKey> >(new lru_map<virtual_time, HashKey>); 
        _hash_table = shared_ptr<lru_map<HashKey, HashValue> > (new lru_map<HashKey, HashValue>); 
    } 
    
    ~CLRUCache(){ 
        _lru_list->clear(); 
        _hash_table->clear(); 
    } 
    
    int set( const HashKey& key, const id &value )&nb

补充:移动开发 , IOS ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,