SDXFrameWork  0.13
SDXFrameWork
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
Pool.h
1 //Copyright © 2014 SDXFramework
2 //[License]GNU Affero General Public License, version 3
3 //[Contact]http://sourceforge.jp/projects/dxframework/
4 #pragma once
5 #include <vector>
6 
7 namespace SDX
8 {
12 class Pool
13 {
14  //メモリプール
15  static const int BS = 65536 * 4;//バッファサイズ、2のn乗にする
16  //BSが大きいほど削除が早くなり、事前に確保するメモリの量が増える
17  int index[7];// = { BS, BS, BS, BS, BS, BS, BS };
18  std::vector<int*> poolS[7];
19 
20  //空き状況
21  std::vector<int> emptyS[7];
22 public:
23  Pool()
24  {
25  for (auto &it : index)
26  {
27  it = BS;
28  }
29  for (auto &it : emptyS)
30  {
31  it.reserve(BS);
32  }
33  }
34 
35  ~Pool()
36  {
37  //確保したメモリを解放
38  for (auto &it : poolS)
39  {
40  for (auto &itt : it)
41  {
42  delete[] itt;
43  }
44  }
45  }
46 
47 
48  template< class T >
49  T* Get()
50  {
51  int size = 0;
52  int buff = 1;
53  static const size_t tSize = sizeof(T);
54 
55  if ( tSize <= 4){}
56  else if (tSize <= 8) { size = 1;; buff = 2; }
57  else if (tSize <= 16) { size = 2; buff = 4; }
58  else if (tSize <= 32) { size = 3; buff = 8; }
59  else if (tSize <= 64) { size = 4; buff = 16; }
60  else if (tSize <= 128) { size = 5; buff = 32; }
61  else if (tSize <= 256) { size = 6; buff = 64; }
62  else
63  {
64  //普通にnewする
65  return new T();
66  }
67 
68  if (emptyS[size].empty())
69  {
70  //大きさ+1して最後尾を返す
71  index[size] += buff;
72  if (index[size] >= BS)
73  {
74  //領域を増やす
75  poolS[size].push_back(new int[BS]);
76  index[size] = 0;
77  }
78 
79  return new(&poolS[size][poolS[size].size() - 1][index[size]]) T();
80  }
81  else
82  {
83  //空きがある場合そこを使う
84  int n = emptyS[size].back();
85  emptyS[size].pop_back();
86  return new(&poolS[size][n / BS][n % BS]) T();
87  }
88  }
89 
90  template< class T>
91  T* Get(const T data)
92  {
93  int size = 0;
94  int buff = 1;
95  static const size_t tSize = sizeof(T);
96 
97  if (tSize <= 4){}
98  else if (tSize <= 8) { size = 1;; buff = 2; }
99  else if (tSize <= 16) { size = 2; buff = 4; }
100  else if (tSize <= 32) { size = 3; buff = 8; }
101  else if (tSize <= 64) { size = 4; buff = 16; }
102  else if (tSize <= 128) { size = 5; buff = 32; }
103  else if (tSize <= 256) { size = 6; buff = 64; }
104  else
105  {
106  //普通にnewする
107  return new T(data);
108  }
109 
110  //大きさ+1して最後尾を返す
111  if ( emptyS[size].empty() )
112  {
113  index[size] += buff;
114  if (index[size] >= BS)
115  {
116  poolS[size].push_back(new int[BS]);
117  index[size] = 0;
118  }
119 
120  return new( &poolS[size][poolS[size].size()-1][index[size]]) T(data);
121  }
122  else
123  {
124  //空きがある場合
125  int n = emptyS[size].back();
126  emptyS[size].pop_back();
127  return new(&poolS[size][n / BS][n % BS]) T(data);
128  }
129  }
130 
131  template< class T>
132  void Destroy(T* pt)
133  {
134  int size = 0;
135  int buff = 1;
136  static const size_t tSize = sizeof(T);
137 
138  if (tSize <= 4) {}
139  else if (tSize <= 8) { size = 1;; buff = 2; }
140  else if (tSize <= 16) { size = 2; buff = 4; }
141  else if (tSize <= 32) { size = 3; buff = 8; }
142  else if (tSize <= 64) { size = 4; buff = 16; }
143  else if (tSize <= 128) { size = 5; buff = 32; }
144  else if (tSize <= 256) { size = 6; buff = 64; }
145  else
146  {
147  //普通にdeleteする
148  delete (void*)pt;
149  return;
150  }
151 
152  int n = -1;
153  int a = 0;
154 
155  //最後まで探して無いなら空きリストには追加しない
156  while( (unsigned int)a < poolS[size].size())
157  {
158  n = ((int*)pt - &poolS[size][a][0]);//0なら先頭要素削除
159  //見つかったら再利用
160  if ( n >= 0 && n < BS)
161  {
162  emptyS[size].push_back(n + a*BS);
163  return;
164  }
165  ++a;
166  }
167  }
168 
169 };
170 
171 }
汎用メモリプール.
Definition: Pool.h:12