.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