c++内存优化:二级间接索引模式内存池
2017-08-14 00:00
369 查看
.H内容如下:
.CPP内容如下:
本文出自 “张宇(数据恢复)” 博客,请务必保留此出处http://zhangyu.blog.51cto.com/197148/680592
/********************************************************* 在一些不确定内存总占用量的情形下,频繁的使用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
相关文章推荐
- c++内存优化:二级间接索引模式内存池
- 我所理解的设计模式(C++实现)—— “一句话总结”和索引
- c++中如何使二级指针能够像数组下标模式访问
- 我所理解的设计模式(C++实现)—— “一句话总结”和索引
- 我所理解的设计模式(C++实现)—— “一句话总结”和索引
- 我所理解的设计模式(C++实现)—— “一句话总结”和索引
- HBase二级索引与Join
- 设计模式之迭代器模式,C++下的讨论
- c++ 设计模式之概括
- 外观模式----C++实现
- 三种单例模式的C++实现
- 设计模式解析和实现(C++)之十五-Observer模式
- C++中的单例模式
- C++设计模式之适配器模式
- 设计模式--桥梁模式C++实现
- c++ 单例模式下的实例自动销毁(单例自动回收器)
- 极客班C++设计模式第二周课程笔记——常用模式(3)
- 设计模式C++实现(11)——装饰模式
- C++单例模式应用实例
- 大话设计模式C++版——工厂模式在COM中的典型应用