使用hash_map list实现用户信息缓冲

//transaddrbuffer.h
#pragma once #include <hash_map> #include <memory> #include <windows.h> #include "unicomodbclib.h"
#pragma pack(push,4)
using stdext::hash_map; using std::list; using std::pair; using std::auto_ptr;
class CTransAddrBuffer { private:  class CacheInfo;  typedef hash_map<__int64, CacheInfo>  _T_Map;  typedef list<_T_Map::iterator>    _T_Queue;  typedef pair<_T_Map::iterator, bool>  _T_Pair;  typedef pair<__int64, CacheInfo>   _T_Value;  typedef list<_T_Map::iterator>::iterator _T_Pointor;
 enum{   CACHE_TIME_OUT = 5,    //超时5m   MAX_CACHE_ITEM = 1024   //缓冲1024  };
 class CacheInfo  {  public:   time_t   mAddTime;   _T_Pointor  moQueueWhere;
  WORD   mwAcsId;   BYTE   mbyConnectionType;   unsigned long  mulIpAddr;   WORD   mwPort;   long   mlLoginTime;
  char   macVersion[VERSION_LEN+1];   //STRU_ODBC_USER_STATUS  moInfo;  };
 static void assign(CacheInfo& to, const STRU_ODBC_USER_STATUS& from)  {   to.mAddTime   = time(NULL);   to.mwAcsId   = from.mwLoginAcsId;   to.mbyConnectionType= from.mbyConnectType;   to.mulIpAddr  = from.mulUserIpAddr;   to.mwPort   = from.mwUserPort;   to.mlLoginTime  = from.mlLoginDate;
  memcpy(to.macVersion, from.macVersion, VERSION_LEN+1);  }
 static void assign(STRU_ODBC_USER_STATUS& to, const CacheInfo& from)  {   to.mwLoginAcsId  = from.mwAcsId;   to.mbyConnectType = from.mbyConnectionType;   to.mulUserIpAddr = from.mulIpAddr;   to.mwUserPort  = from.mwPort;   to.mlLoginDate  = from.mlLoginTime;
  memcpy(to.macVersion, from.macVersion, VERSION_LEN+1);  }
 int   hit;  int ClearOldItem();  CTransAddrBuffer(void);  ~CTransAddrBuffer(void);  CRITICAL_SECTION moAccess;
 _T_Queue moQueue;  _T_Map  moCache;
 static CTransAddrBuffer* instance;
 friend class auto_ptr<CTransAddrBuffer>; public:  void Dump();  void CachUserInfo(__int64 aiUserID, STRU_ODBC_USER_STATUS& aoInfo);  bool GetUserInfo(__int64 aiUserID, STRU_ODBC_USER_STATUS& aoInfo);
 static CTransAddrBuffer& GetInstance();
 static void destructure()  {   CTransAddrBuffer* temp = instance;   instance = NULL;
  delete temp;  } };
#pragma pack(pop)
//transaddrbuffer.cpp
#include "stdafx.h" #include "./transaddrbuffer.h"
#include "help/AutoLock.h"
//静态初始化 CTransAddrBuffer* CTransAddrBuffer::instance = NULL;
CTransAddrBuffer::CTransAddrBuffer(void) {  //printf("CTransAddrBuffer 构造 %X/n", this);  hit = 0;  InitializeCriticalSection(&moAccess); }
CTransAddrBuffer::~CTransAddrBuffer(void) {  //printf("CTransAddrBuffer 析构 %X/n", this);  DeleteCriticalSection(&moAccess); }
//清除超时的缓冲对象 int CTransAddrBuffer::ClearOldItem() {  int ret = 0;  time_t now = time(NULL);  _T_Map::iterator iterator;
 if(moCache.size() > 200)  {   while(!moQueue.empty())   {    iterator = moQueue.back();    if(now - iterator->second.mAddTime > CACHE_TIME_OUT)    {     moQueue.pop_back();
    //清楚缓存表     moCache.erase(iterator);     ret ++;    }    else    {     break;    }   }  }  return ret; }
//输出调试信息清除没有用的缓冲项 void CTransAddrBuffer::Dump() {  int liDelItems;  int liHit;
 int liQueueSize;  int liMapSize;
 {   CAutoLock lock(moAccess);   liMapSize = moCache.size();   liQueueSize = moQueue.size();
  liHit = hit;   hit = 0;   liDelItems = ClearOldItem();  }
 RecordLog0("CTransAddrBuffer::CachUserInfo Map size:%d Queue size:%d./n", liMapSize, liQueueSize);  RecordLog0("CTransAddrBuffer::CachUserInfo Hit:%d Delete time out:%d/n", liHit, liDelItems); }
//缓冲用户信息 void CTransAddrBuffer::CachUserInfo(__int64 aiUserID, STRU_ODBC_USER_STATUS& aoInfo) {  _T_Map::iterator iterator;
 CAutoLock lock(moAccess);
 try  {   //保证队列长度   iterator = moCache.find(aiUserID);
  if(iterator != moCache.end())   {    //更新缓存信息    assign(iterator->second, aoInfo);
   //更新在队列的位置    if(moQueue.begin()!=(iterator->second.moQueueWhere))    {     moQueue.erase(iterator->second.moQueueWhere);     moQueue.push_front(iterator);     iterator->second.moQueueWhere = moQueue.begin();    }   }   else   {    _T_Pair ret;    _T_Value value;
   value.first = aiUserID;    assign(value.second, aoInfo);
   if(moQueue.size() >= MAX_CACHE_ITEM)    {     iterator = moQueue.back();     moQueue.pop_back();     moCache.erase(iterator);    }
   //添加到队列    ret = moCache.insert(value);
   if(ret.second)    {     moQueue.push_front(ret.first);     (ret.first)->second.moQueueWhere = moQueue.begin();    }   }  }  catch(...)  {   moCache.erase(aiUserID);
  RecordLog0("CTransAddrBuffer::CachUserInfo Catch Exception/n");  } }
//查找用户信息 bool CTransAddrBuffer::GetUserInfo(__int64 aiUserID, STRU_ODBC_USER_STATUS& aoInfo) {  CAutoLock lock(moAccess);
 _T_Map::iterator it = moCache.find(aiUserID);
 if(it==moCache.end())  {   return false;  }  if(time(NULL) - it->second.mAddTime < CACHE_TIME_OUT)  {   hit ++;   assign(aoInfo, it->second);   aoInfo.mbiUserId = aiUserID;
  return true;  }  return false; }
//返回实例 CTransAddrBuffer& CTransAddrBuffer::GetInstance() {  if(instance)  {   return *instance;  }  else  {   auto_ptr<CTransAddrBuffer> pointer(new CTransAddrBuffer());
  if(0 == InterlockedCompareExchange((LONG*)&instance, (LONG)pointer.get(), 0))   {    pointer.release();
   atexit(destructure);   }  }
 return *instance; }
转http://blog.sina.com.cn/s/blog_5398d388010004k2.html

你可能感兴趣的:(使用hash_map list实现用户信息缓冲)