您的位置:首页 > 编程语言 > C语言/C++

c++内存优化:二级间接索引模式内存池

2017-08-14 00:00 369 查看
.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;

};

.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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  优化 休闲 职场