C++内存优化:二级间接索引模式内存池
副标题#e#
.H内容如下:
/*********************************************************
在一些不确定内存总占用量的景象下,频繁的利用new申请内存,再通过链表
举办索引好像是很通例的做法。自然,也很难做到随机定位。
下面的内存池类是用二层索引表来对内存举办大块分别,任何一个块均只需索
引3次即可定位。
索引数量,每索引块的分派单位数量,以及分派单位的字节长度均需为2的整数
次幂(为了运算时的效率)
//by:www.datahf.net zhangyu(zhangyu.blog.51cto.com)
*********************************************************/
class MemTable
{
public:
MemTable(void);
public:
~MemTable(void);
public:
void CREATE(MemTableIn *in_m);
void DEL();
LPSTR NEW();//分派一个unit
LPSTR NEW_CONTINUEOUS(UINT n);//用于持续分派若干个unit
UINT NEW(UINT n); //用于可碎片方法分派若干个unit
LPSTR GET(UINT n);//用来得到第n个分派的指针地点
int get_totle_unitnum();
public:
MemTableIn in;
LPSTR **pDouble_Indirect;
LPSTR lpBitmap;
LPSTR *pIndirect;
LPSTR m_lpFirstFree;
int nFree[3];//0暗示二级索引的自由,1暗示1级索引的自由,2暗示块自由索引号
INT32 m_EndBlkUseredUnits;
int m_Vblkbytes;
UINT m_UnitTotalNum;
UINT m_log2Rindexs,m_log2Runits,m_log2Rbitmap,m_log2Lindexs,m_log2Lunits,m_log2Lbitmap;
UINT m_log2UnitBytes;
UINT m_index2ID,m_index1ID,m_UnitID;
};
#p#副标题#e#
.CPP内容如下:
/**
* ffs - Find the first set bit in an int
* @x:
*
* Description...用来统计一个整型数据的最高为1的位,后头有几多位。
*换个说法:从最高位开始找1,找到1后,看这个二进制数据1000....000是2的屡次方
*
* Returns:
*/
int ffs(int x)
{
int r = 1;
if (!x)
return 0;
if (!(x & 0xffff)) {
x >>= 16;
r += 16;
}
if (!(x & 0xff)) {
x >>= 8;
r += 8;
}
if (!(x & 0xf)) {
x >>= 4;
r += 4;
}
if (!(x & 3)) {
x >>= 2;
r += 2;
}
if (!(x & 1)) {
x >>= 1;
r += 1;
}
return r;
}
LPSTR MemTree::GET(MemTreeHead *pHead,UINT n)
{
int t;
LPSTR lpt;
int i,ii;
//判定是否直接存储
if(n<m.rootDirectUnitNum)
return pHead->lpRootUnit + n*m.Vsizeof;
else
t=n-m.rootDirectUnitNum;
for(i=1;i<DEEP;i++)
{
if(t<TBT[i][0])
break;
t-=TBT[i][0];
}
//i即是深度,t是深度内的n
lpt=pHead->pROOT_INDEX[i-1];
int D;
for(ii=1;ii<i;ii++)
{
D=t /TBT[i][ii];
t=t % TBT[i][ii];
lpt=*(LPSTR*)(lpt+sizeof(LPSTR)*D);
}
return (lpt + t*m.Vsizeof);
}
MemTable::MemTable(void)
{
}
MemTable::~MemTable(void)
{
//释放所有空间
for(int i=0;i<in.nIndexNum;i++)
{
LPSTR *pp=pDouble_Indirect[i];
if(pp==NULL)
break;
for(int ii=0;ii<in.nIndexNum;ii++)
{
LPSTR p=pp[ii];
if(p==NULL)
break;
else
delete [] p;
}
delete [] pp;
}
delete [] pDouble_Indirect;
}
void MemTable::CREATE(MemTableIn *in_m)
{
//1、初始化一些参考块
memset(&in,0,sizeof(in));
in=*in_m;
m_UnitTotalNum=0;
nFree[0]=nFree[1]=nFree[2]=0;
m_Vblkbytes= in.nUnitBytes *in.nUnitPerIndex;
m_log2Runits=ffs(in.nUnitPerIndex)-1;
m_log2Rindexs=ffs(in.nIndexNum)-1;
m_log2UnitBytes=ffs(in.nUnitBytes)-1;
m_log2Lindexs=sizeof(UINT)*8-m_log2Rindexs;
m_log2Lunits=sizeof(UINT)*8-m_log2Runits;
//2、初始化二级索引表
pDouble_Indirect=new LPSTR* [in.nIndexNum];
memset(pDouble_Indirect,0,in.nIndexNum*sizeof(LPSTR));
nFree[0]=in.nIndexNum;
}
LPSTR MemTable::NEW()
{
LPSTR lpReturn;
if(nFree[2]==0)//直接块用光了
{
if(nFree[1]==0)
{
if(nFree[0]==0)
return NULL;//写日志:到达最大分派数量
pIndirect=pDouble_Indirect[in.nIndexNum - nFree[0]]=new LPSTR [in.nIndexNum];
memset(pIndirect,0,in.nIndexNum*sizeof(LPSTR));
nFree[1]=in.nIndexNum-1;
lpReturn=pIndirect[0]=new char[m_Vblkbytes];
memset(lpReturn,0,m_Vblkbytes);
nFree[2]=in.nUnitPerIndex-1;
m_lpFirstFree = lpReturn + in.nUnitBytes;
nFree[0]--;
}
else
{
lpReturn=pIndirect[in.nIndexNum - nFree[1]]=new char[m_Vblkbytes];
memset(lpReturn,0,m_Vblkbytes);
nFree[1]--;
nFree[2]=in.nUnitPerIndex-1;
m_lpFirstFree = lpReturn + in.nUnitBytes;
}
}
else
{
lpReturn=m_lpFirstFree;
nFree[2]--;
m_lpFirstFree += in.nUnitBytes;
}
m_UnitTotalNum++;
return lpReturn;
}//by:www.datahf.net zhangyu(zhangyu.blog.51cto.com)
UINT MemTable::NEW(UINT n)
{
UINT nReturn=m_UnitTotalNum;
for(int i=0;i<n;i++)
NEW();
return nReturn;
}
LPSTR MemTable::NEW_CONTINUEOUS(UINT n)
{
LPSTR lpReturn;
if(n>in.nUnitPerIndex)
return NULL;
if(nFree[2]>=n)
{
nFree[2]-=n;
lpReturn=m_lpFirstFree;
m_UnitTotalNum+=n;
m_lpFirstFree += (n*in.nUnitBytes);
}
else
{
m_UnitTotalNum+=nFree[2];//剩余空间保存、忽略
nFree[2]=0;
lpReturn=NEW();
nFree[2] -= (n-1);
m_lpFirstFree += ((n-1)*in.nUnitBytes);
m_UnitTotalNum += (n-1);
}
return lpReturn;
}
LPSTR MemTable::GET(UINT n)
{ //by:www.datahf.net zhangyu(zhangyu.blog.51cto.com)
if(n>=m_UnitTotalNum)
return NULL;//写日志:高出范畴
m_UnitID=n<< m_log2Lunits >>m_log2Lunits;
m_index1ID=n >> m_log2Runits;
m_index2ID=m_index1ID >> m_log2Rindexs;
m_index1ID=m_index1ID <<m_log2Lindexs >>m_log2Lindexs;
return (pDouble_Indirect[m_index2ID][m_index1ID] + (m_UnitID<<m_log2UnitBytes));
}
void MemTable::DEL()
{
}
本文出自 “张宇(数据规复)” 博客,请务必保存此出处http://zhangyu.blog.51cto.com/197148/680592