#ifndef _INCLUDE_FIXLENMEMPOOLNOLOCK_H_
#define _INCLUDE_FIXLENMEMPOOLNOLOCK_H_
#include "log.h"
#include <string>
namespace XUANXUAN
{
//无锁缓存 单线程使用
class CFixLenMemPoolNoLock
{
public:
struct TBigerItem
{
TBigerItem(unsigned int nMemLen)
:m_pNextItem(NULL)
,m_nMemLen(nMemLen)
{
}
TBigerItem* m_pNextItem;
const unsigned int m_nMemLen;
char m_pMemHead[1];
};
struct TSmallItem
{
TSmallItem* m_pNextItem;
};
CFixLenMemPoolNoLock(int nFixLen)
:m_nSmallItemLen(nFixLen>sizeof(TSmallItem)?nFixLen:sizeof(TSmallItem))
{
m_nTotalMemLen = 0;
m_nBigItemNum = 0;
m_pBigHead = NULL;
m_pBigTail = NULL;
m_pSmlHead = NULL;
m_pSmlTail = NULL;
m_nGetNum = 0;
m_nPutNum = 0;
static int s_PoolID = 0;
char pName[64];
sprintf(pName,"pool_%02d<%04u>",s_PoolID++,m_nSmallItemLen);
m_strName = pName;
}
void SetPoolName(const char* pName)
{
m_strName = pName;
}
char* GetCacheMem(int nRealLen)
{
return _GetCacheMem(nRealLen);
}
void PutCacheMem(char* &pMem,int nRealLen)
{
_PutCacheMem(pMem,nRealLen);
}
unsigned int GetMemInfo(string& strMemInfo)
{
char memBuffer[128];
sprintf(memBuffer,"<%06u> sumMemLen=%-9u totalNum=%-6u useNum=%-6u\n",m_nSmallItemLen,m_nTotalMemLen,m_nPutNum+m_nGetNum,m_nPutNum);
strMemInfo = memBuffer;
return m_nTotalMemLen;
}
void ClearMem()
{
if (m_nPutNum==0)
{
m_pSmlHead = NULL;
m_pSmlTail = NULL;
m_nPutNum = 0;
m_nGetNum = 0;
m_nTotalMemLen = 0;
m_nBigItemNum = 0;
while(m_pBigHead)
{
char* pFreeMem = (char*)m_pBigHead;
m_pBigHead = m_pBigHead->m_pNextItem;
delete[] pFreeMem;
}
m_pBigHead = NULL;
m_pBigTail = NULL;
}
}
private:
char* _GetCacheMem(int nRealLen)
{
LOG(LOG_DEBUG5,"%s nBigNum=%u canGetNum=%u canPutNum=%u nrealLen=%u",m_strName.c_str(),m_nBigItemNum,m_nGetNum,m_nPutNum,nRealLen);
if (NULL == m_pSmlHead)
{
_newsmallitem();
}
return _popfront_proxy();
}
void _PutCacheMem(char* &pMem,int nRealLen)
{
LOG(LOG_DEBUG5,"%s nBigNum=%u canGetNum=%u canPutNum=%u nrealLen=%u",m_strName.c_str(),m_nBigItemNum,m_nGetNum,m_nPutNum,nRealLen);
_pushback_proxy((TSmallItem*)pMem);
pMem = NULL;
}
private:
void _newsmallitem()
{
TBigerItem* pNewBigerItem = NULL;
_getbigeritem(pNewBigerItem);
for(unsigned int i=0;i<pNewBigerItem->m_nMemLen/m_nSmallItemLen;++i)
{
TSmallItem* pNewSmallItem = (TSmallItem*)(pNewBigerItem->m_pMemHead+i*m_nSmallItemLen);
_pushback(pNewSmallItem);
}
}
void _getbigeritem(TBigerItem*& refBigerItem)
{
m_nBigItemNum++;
unsigned int nBigItemLen = sizeof(TBigerItem);
if (m_nSmallItemLen>=512)
{
nBigItemLen += 32*m_nSmallItemLen;
}
else
{
nBigItemLen += 512*m_nSmallItemLen;
}
m_nTotalMemLen += nBigItemLen;
//LOG(LOG_CRITICAL,"allocbuff size=%u",nBigItemLen);
refBigerItem = new(new char[nBigItemLen]) TBigerItem(nBigItemLen-sizeof(TBigerItem));
refBigerItem->m_pNextItem = NULL;
if (m_pBigTail)
{
m_pBigTail->m_pNextItem = refBigerItem;
}
else
{
m_pBigHead = refBigerItem;
}
m_pBigTail = refBigerItem;
}
char* _popfront_proxy()
{
++m_nPutNum;
TSmallItem* pSmallItem = NULL;
_popfront(pSmallItem);
return (char*)pSmallItem;
}
void _pushback_proxy(TSmallItem* pMemItem)
{
--m_nPutNum;
_pushback(pMemItem);
}
private:
void _popfront(TSmallItem*& pMemItem)
{
pMemItem = NULL;
if (m_pSmlHead)
{
--m_nGetNum;
pMemItem = m_pSmlHead;
if (m_pSmlTail == m_pSmlHead)
{ //最后一块
m_pSmlHead = NULL;
m_pSmlTail = NULL;
}
else
{
m_pSmlHead = m_pSmlHead->m_pNextItem;
}
pMemItem->m_pNextItem = NULL;
}
}
void _pushback(TSmallItem*& pMemItem)
{
++m_nGetNum;
if (m_pSmlTail)
{
m_pSmlTail->m_pNextItem = pMemItem;
}
else
{
m_pSmlHead = pMemItem;
}
m_pSmlTail = pMemItem;
pMemItem->m_pNextItem = NULL;
pMemItem = NULL;
}
protected:
string m_strName; //名称
const unsigned int m_nSmallItemLen; //小块内存大小
TBigerItem* m_pBigHead;
TBigerItem* m_pBigTail;
unsigned int m_nBigItemNum; //大缓存块数目
unsigned int m_nTotalMemLen; //总内存大小
unsigned int m_nGetNum; //可申请数目
unsigned int m_nPutNum; //可释放数目
TSmallItem* m_pSmlHead;
TSmallItem* m_pSmlTail;
};
}
#endif
#define _INCLUDE_FIXLENMEMPOOLNOLOCK_H_
#include "log.h"
#include <string>
namespace XUANXUAN
{
//无锁缓存 单线程使用
class CFixLenMemPoolNoLock
{
public:
struct TBigerItem
{
TBigerItem(unsigned int nMemLen)
:m_pNextItem(NULL)
,m_nMemLen(nMemLen)
{
}
TBigerItem* m_pNextItem;
const unsigned int m_nMemLen;
char m_pMemHead[1];
};
struct TSmallItem
{
TSmallItem* m_pNextItem;
};
CFixLenMemPoolNoLock(int nFixLen)
:m_nSmallItemLen(nFixLen>sizeof(TSmallItem)?nFixLen:sizeof(TSmallItem))
{
m_nTotalMemLen = 0;
m_nBigItemNum = 0;
m_pBigHead = NULL;
m_pBigTail = NULL;
m_pSmlHead = NULL;
m_pSmlTail = NULL;
m_nGetNum = 0;
m_nPutNum = 0;
static int s_PoolID = 0;
char pName[64];
sprintf(pName,"pool_%02d<%04u>",s_PoolID++,m_nSmallItemLen);
m_strName = pName;
}
void SetPoolName(const char* pName)
{
m_strName = pName;
}
char* GetCacheMem(int nRealLen)
{
return _GetCacheMem(nRealLen);
}
void PutCacheMem(char* &pMem,int nRealLen)
{
_PutCacheMem(pMem,nRealLen);
}
unsigned int GetMemInfo(string& strMemInfo)
{
char memBuffer[128];
sprintf(memBuffer,"<%06u> sumMemLen=%-9u totalNum=%-6u useNum=%-6u\n",m_nSmallItemLen,m_nTotalMemLen,m_nPutNum+m_nGetNum,m_nPutNum);
strMemInfo = memBuffer;
return m_nTotalMemLen;
}
void ClearMem()
{
if (m_nPutNum==0)
{
m_pSmlHead = NULL;
m_pSmlTail = NULL;
m_nPutNum = 0;
m_nGetNum = 0;
m_nTotalMemLen = 0;
m_nBigItemNum = 0;
while(m_pBigHead)
{
char* pFreeMem = (char*)m_pBigHead;
m_pBigHead = m_pBigHead->m_pNextItem;
delete[] pFreeMem;
}
m_pBigHead = NULL;
m_pBigTail = NULL;
}
}
private:
char* _GetCacheMem(int nRealLen)
{
LOG(LOG_DEBUG5,"%s nBigNum=%u canGetNum=%u canPutNum=%u nrealLen=%u",m_strName.c_str(),m_nBigItemNum,m_nGetNum,m_nPutNum,nRealLen);
if (NULL == m_pSmlHead)
{
_newsmallitem();
}
return _popfront_proxy();
}
void _PutCacheMem(char* &pMem,int nRealLen)
{
LOG(LOG_DEBUG5,"%s nBigNum=%u canGetNum=%u canPutNum=%u nrealLen=%u",m_strName.c_str(),m_nBigItemNum,m_nGetNum,m_nPutNum,nRealLen);
_pushback_proxy((TSmallItem*)pMem);
pMem = NULL;
}
private:
void _newsmallitem()
{
TBigerItem* pNewBigerItem = NULL;
_getbigeritem(pNewBigerItem);
for(unsigned int i=0;i<pNewBigerItem->m_nMemLen/m_nSmallItemLen;++i)
{
TSmallItem* pNewSmallItem = (TSmallItem*)(pNewBigerItem->m_pMemHead+i*m_nSmallItemLen);
_pushback(pNewSmallItem);
}
}
void _getbigeritem(TBigerItem*& refBigerItem)
{
m_nBigItemNum++;
unsigned int nBigItemLen = sizeof(TBigerItem);
if (m_nSmallItemLen>=512)
{
nBigItemLen += 32*m_nSmallItemLen;
}
else
{
nBigItemLen += 512*m_nSmallItemLen;
}
m_nTotalMemLen += nBigItemLen;
//LOG(LOG_CRITICAL,"allocbuff size=%u",nBigItemLen);
refBigerItem = new(new char[nBigItemLen]) TBigerItem(nBigItemLen-sizeof(TBigerItem));
refBigerItem->m_pNextItem = NULL;
if (m_pBigTail)
{
m_pBigTail->m_pNextItem = refBigerItem;
}
else
{
m_pBigHead = refBigerItem;
}
m_pBigTail = refBigerItem;
}
char* _popfront_proxy()
{
++m_nPutNum;
TSmallItem* pSmallItem = NULL;
_popfront(pSmallItem);
return (char*)pSmallItem;
}
void _pushback_proxy(TSmallItem* pMemItem)
{
--m_nPutNum;
_pushback(pMemItem);
}
private:
void _popfront(TSmallItem*& pMemItem)
{
pMemItem = NULL;
if (m_pSmlHead)
{
--m_nGetNum;
pMemItem = m_pSmlHead;
if (m_pSmlTail == m_pSmlHead)
{ //最后一块
m_pSmlHead = NULL;
m_pSmlTail = NULL;
}
else
{
m_pSmlHead = m_pSmlHead->m_pNextItem;
}
pMemItem->m_pNextItem = NULL;
}
}
void _pushback(TSmallItem*& pMemItem)
{
++m_nGetNum;
if (m_pSmlTail)
{
m_pSmlTail->m_pNextItem = pMemItem;
}
else
{
m_pSmlHead = pMemItem;
}
m_pSmlTail = pMemItem;
pMemItem->m_pNextItem = NULL;
pMemItem = NULL;
}
protected:
string m_strName; //名称
const unsigned int m_nSmallItemLen; //小块内存大小
TBigerItem* m_pBigHead;
TBigerItem* m_pBigTail;
unsigned int m_nBigItemNum; //大缓存块数目
unsigned int m_nTotalMemLen; //总内存大小
unsigned int m_nGetNum; //可申请数目
unsigned int m_nPutNum; //可释放数目
TSmallItem* m_pSmlHead;
TSmallItem* m_pSmlTail;
};
}
#endif