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

简介:

.H内容如下:

 
 
  1. /********************************************************* 
  2. 在一些不确定内存总占用量的情形下,频繁的使用new申请内存,再通过链表 
  3. 进行索引似乎是很常规的做法。自然,也很难做到随机定位。 
  4. 下面的内存池类是用二层索引表来对内存进行大块划分,任何一个块均只需索 
  5. 引3次即可定位。 
  6. 索引数量,每索引块的分配单元数量,以及分配单元的字节长度均需为2的整数 
  7. 次幂(为了运算时的效率)
  8. //by:www.datahf.net zhangyu(zhangyu.blog.51cto.com) 
  9. *********************************************************/ 
  10. class MemTable 
  11. public
  12.     MemTable(void); 
  13. public
  14.     ~MemTable(void); 
  15. public
  16.     void CREATE(MemTableIn *in_m);  
  17.     void DEL(); 
  18.     LPSTR NEW();//分配一个unit 
  19.     LPSTR NEW_CONTINUEOUS(UINT n);//用于连续分配若干个unit 
  20.     UINT NEW(UINT n); //用于可碎片方式分配若干个unit 
  21.     LPSTR GET(UINT n);//用来获得第n个分配的指针地址 
  22.     int get_totle_unitnum(); 
  23. public
  24.     MemTableIn in; 
  25.     LPSTR **pDouble_Indirect; 
  26.     LPSTR lpBitmap; 
  27.     LPSTR *pIndirect; 
  28.  
  29.     LPSTR m_lpFirstFree; 
  30.     int nFree[3];//0表示二级索引的自由,1表示1级索引的自由,2表示块自由索引号 
  31.     INT32 m_EndBlkUseredUnits; 
  32.     int m_Vblkbytes; 
  33.     UINT m_UnitTotalNum; 
  34.     UINT m_log2Rindexs,m_log2Runits,m_log2Rbitmap,m_log2Lindexs,m_log2Lunits,m_log2Lbitmap; 
  35.     UINT m_log2UnitBytes; 
  36.     UINT m_index2ID,m_index1ID,m_UnitID; 
  37. }; 

.CPP内容如下: 

 
 
  1. /** 
  2. * ffs - Find the first set bit in an int 
  3. * @x: 
  4. * 
  5. * Description...用来统计一个整型数据的最高为1的位,后面有多少位。 
  6. *换个说法:从最高位开始找1,找到1后,看这个二进制数据1000....000是2的几次方 
  7. * 
  8. * Returns: 
  9. */ 
  10. int ffs(int x) 
  11.     int r = 1; 
  12.  
  13.     if (!x) 
  14.         return 0; 
  15.     if (!(x & 0xffff)) { 
  16.         x >>= 16; 
  17.         r += 16; 
  18.     } 
  19.     if (!(x & 0xff)) { 
  20.         x >>= 8; 
  21.         r += 8; 
  22.     } 
  23.     if (!(x & 0xf)) { 
  24.         x >>= 4; 
  25.         r += 4; 
  26.     } 
  27.     if (!(x & 3)) { 
  28.         x >>= 2; 
  29.         r += 2; 
  30.     } 
  31.     if (!(x & 1)) { 
  32.         x >>= 1; 
  33.         r += 1; 
  34.     } 
  35.     return r; 
  36. LPSTR MemTree::GET(MemTreeHead *pHead,UINT n) 
  37.     int t; 
  38.     LPSTR lpt; 
  39.     int i,ii; 
  40.     //判断是否直接存储 
  41.     if(n<m.rootDirectUnitNum) 
  42.         return pHead->lpRootUnit + n*m.Vsizeof; 
  43.     else 
  44.         t=n-m.rootDirectUnitNum; 
  45.  
  46.     for(i=1;i<DEEP;i++) 
  47.     { 
  48.         if(t<TBT[i][0]) 
  49.             break
  50.         t-=TBT[i][0]; 
  51.     } 
  52.     //i便是深度,t是深度内的n 
  53.     lpt=pHead->pROOT_INDEX[i-1]; 
  54.     int D; 
  55.     for(ii=1;ii<i;ii++) 
  56.     { 
  57.         D=t /TBT[i][ii]; 
  58.         t=t % TBT[i][ii]; 
  59.         lpt=*(LPSTR*)(lpt+sizeof(LPSTR)*D); 
  60.     } 
  61.     return (lpt +   t*m.Vsizeof); 
  62.  
  63.  
  64. MemTable::MemTable(void
  65.  
  66. MemTable::~MemTable(void
  67.     //释放所有空间 
  68.     for(int i=0;i<in.nIndexNum;i++) 
  69.     { 
  70.         LPSTR *pp=pDouble_Indirect[i]; 
  71.         if(pp==NULL) 
  72.             break
  73.         for(int ii=0;ii<in.nIndexNum;ii++) 
  74.         { 
  75.             LPSTR p=pp[ii]; 
  76.             if(p==NULL) 
  77.                 break
  78.             else 
  79.                 delete [] p; 
  80.         } 
  81.         delete [] pp; 
  82.     } 
  83.     delete [] pDouble_Indirect; 
  84. void MemTable::CREATE(MemTableIn *in_m) 
  85.     //1、初始化一些参考块 
  86.     memset(&in,0,sizeof(in)); 
  87.     in=*in_m; 
  88.     m_UnitTotalNum=0; 
  89.     nFree[0]=nFree[1]=nFree[2]=0; 
  90.  
  91.     m_Vblkbytes= in.nUnitBytes *in.nUnitPerIndex; 
  92.     m_log2Runits=ffs(in.nUnitPerIndex)-1; 
  93.     m_log2Rindexs=ffs(in.nIndexNum)-1; 
  94.     m_log2UnitBytes=ffs(in.nUnitBytes)-1; 
  95.  
  96.     m_log2Lindexs=sizeof(UINT)*8-m_log2Rindexs; 
  97.     m_log2Lunits=sizeof(UINT)*8-m_log2Runits; 
  98.      
  99.  
  100.  
  101.     //2、初始化二级索引表 
  102.     pDouble_Indirect=new LPSTR* [in.nIndexNum]; 
  103.     memset(pDouble_Indirect,0,in.nIndexNum*sizeof(LPSTR)); 
  104.     nFree[0]=in.nIndexNum; 
  105. LPSTR MemTable::NEW() 
  106.     LPSTR lpReturn; 
  107.     if(nFree[2]==0)//直接块用光了 
  108.     { 
  109.         if(nFree[1]==0) 
  110.         { 
  111.             if(nFree[0]==0) 
  112.                 return NULL;//写日志:达到最大分配数量 
  113.  
  114.             pIndirect=pDouble_Indirect[in.nIndexNum - nFree[0]]=new LPSTR [in.nIndexNum]; 
  115.             memset(pIndirect,0,in.nIndexNum*sizeof(LPSTR)); 
  116.             nFree[1]=in.nIndexNum-1; 
  117.  
  118.             lpReturn=pIndirect[0]=new char[m_Vblkbytes]; 
  119.             memset(lpReturn,0,m_Vblkbytes); 
  120.             nFree[2]=in.nUnitPerIndex-1; 
  121.             m_lpFirstFree = lpReturn + in.nUnitBytes;    
  122.             nFree[0]--; 
  123.              
  124.         } 
  125.         else 
  126.         { 
  127.             lpReturn=pIndirect[in.nIndexNum - nFree[1]]=new char[m_Vblkbytes]; 
  128.             memset(lpReturn,0,m_Vblkbytes); 
  129.             nFree[1]--; 
  130.             nFree[2]=in.nUnitPerIndex-1; 
  131.             m_lpFirstFree = lpReturn + in.nUnitBytes; 
  132.         } 
  133.     } 
  134.     else 
  135.     { 
  136.         lpReturn=m_lpFirstFree; 
  137.         nFree[2]--; 
  138.         m_lpFirstFree += in.nUnitBytes; 
  139.     } 
  140.     m_UnitTotalNum++; 
  141.     return lpReturn; 
  142.  
  143. }//by:www.datahf.net zhangyu(zhangyu.blog.51cto.com) 
  144. UINT MemTable::NEW(UINT n) 
  145.     UINT nReturn=m_UnitTotalNum; 
  146.     for(int i=0;i<n;i++) 
  147.         NEW(); 
  148.     return nReturn; 
  149.  
  150. LPSTR MemTable::NEW_CONTINUEOUS(UINT n) 
  151.     LPSTR lpReturn; 
  152.     if(n>in.nUnitPerIndex) 
  153.         return NULL; 
  154.  
  155.     if(nFree[2]>=n) 
  156.     { 
  157.         nFree[2]-=n; 
  158.         lpReturn=m_lpFirstFree; 
  159.         m_UnitTotalNum+=n; 
  160.         m_lpFirstFree += (n*in.nUnitBytes); 
  161.     } 
  162.     else 
  163.     { 
  164.         m_UnitTotalNum+=nFree[2];//剩余空间保留、忽略 
  165.         nFree[2]=0; 
  166.         lpReturn=NEW(); 
  167.         nFree[2] -= (n-1); 
  168.         m_lpFirstFree += ((n-1)*in.nUnitBytes); 
  169.         m_UnitTotalNum += (n-1); 
  170.     } 
  171.     return lpReturn; 
  172. LPSTR MemTable::GET(UINT n) 
  173. //by:www.datahf.net zhangyu(zhangyu.blog.51cto.com) 
  174.     if(n>=m_UnitTotalNum) 
  175.         return NULL;//写日志:超过范围 
  176.     m_UnitID=n<< m_log2Lunits >>m_log2Lunits; 
  177.     m_index1ID=n >> m_log2Runits; 
  178.     m_index2ID=m_index1ID >> m_log2Rindexs; 
  179.     m_index1ID=m_index1ID <<m_log2Lindexs >>m_log2Lindexs; 
  180.  
  181.     return (pDouble_Indirect[m_index2ID][m_index1ID] + (m_UnitID<<m_log2UnitBytes)); 
  182.  
  183. void MemTable::DEL() 
  184.  
  185.  









本文转自 张宇 51CTO博客,原文链接:http://blog.51cto.com/zhangyu/680592,如需转载请自行联系原作者
目录
相关文章
|
29天前
|
存储 Java 编译器
C++:内存管理|new和delete
C++:内存管理|new和delete
|
29天前
|
存储 算法 编译器
【C++ 内存管理 重载new/delete 运算符 新特性】深入探索C++14 新的/删除的省略(new/delete elision)的原理与应用
【C++ 内存管理 重载new/delete 运算符 新特性】深入探索C++14 新的/删除的省略(new/delete elision)的原理与应用
45 0
|
26天前
|
存储 Linux C语言
【C++练级之路】【Lv.5】动态内存管理(都2023年了,不会有人还不知道new吧?)
【C++练级之路】【Lv.5】动态内存管理(都2023年了,不会有人还不知道new吧?)
|
26天前
|
安全 程序员 C++
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
101 0
|
27天前
|
算法 编译器 程序员
深入理解C++编译模式:了解Debug和Release的区别
深入理解C++编译模式:了解Debug和Release的区别
61 2
|
27天前
|
存储 Linux 程序员
【Linux C/C++ 堆内存分布】深入理解Linux进程的堆空间管理
【Linux C/C++ 堆内存分布】深入理解Linux进程的堆空间管理
72 0
|
27天前
|
算法 Java C++
【C/C++ 内存知识扩展】内存不足的可能性分析
【C/C++ 内存知识扩展】内存不足的可能性分析
12 0
|
27天前
|
存储 算法 Linux
深入理解Linux内存管理brk 和 sbrk 与以及使用C++ list实现内存分配器
深入理解Linux内存管理brk 和 sbrk 与以及使用C++ list实现内存分配器
34 0
|
29天前
|
设计模式 算法 编译器
【C/C++ PIMPL模式 】 深入探索C++中的PIMPL模式
【C/C++ PIMPL模式 】 深入探索C++中的PIMPL模式
51 0
|
29天前
|
缓存 Linux iOS开发
【C/C++ 集成内存调试、内存泄漏检测和性能分析的工具 Valgrind 】Linux 下 Valgrind 工具的全面使用指南
【C/C++ 集成内存调试、内存泄漏检测和性能分析的工具 Valgrind 】Linux 下 Valgrind 工具的全面使用指南
64 1

热门文章

最新文章