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

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

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

 

posted on 2017-03-28 17:04  北亚数据恢复  阅读(406)  评论(0编辑  收藏  举报

导航