//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