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