1 /*
2    Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 #ifndef FOR_LIB_POOL_H
26 #define FOR_LIB_POOL_H
27 
28 #define JAM_FILE_ID 398
29 
30 
31 
32 //===========================================================================
33 //
34 // .PUBLIC
35 //
36 //===========================================================================
37 
38 ////////////////////////////////////////////////////////////////
39 //
40 // enum { defInitSize = 256, defIncSize  = 64 };
41 // Description: type to store initial and incremental size in.
42 //
43 ////////////////////////////////////////////////////////////////
44 //
45 // Pool(int anInitSize = defInitSize, int anIncSize = defIncSize);
46 // Description:
47 //   Constructor. Allocates anInitSize of objects <template argument>.
48 //   When the pool runs out of elements, anIncSize elements are added to the
49 //   pool. (When the pool is not optimized to allocate multiple elements
50 //   more efficient, the anIncSize MUST be set to 1 to get the best
51 //   performance...
52 //
53 // Parameters:
54 //   defInitSize: Initial size of the pool (# of elements in the pool)
55 //   defIncSize:  # of elements added to the pool when a request to an empty
56 //    pool is made.
57 // Return value:
58 //      _
59 // Errors:
60 //      -
61 // Asserts:
62 //   _
63 //
64 ////////////////////////////////////////////////////////////////
65 //
66 // virtual ~Pool();
67 // Description:
68 //   Elements in the pool are all deallocated.
69 // Parameters:
70 //   _
71 // Return value:
72 //   _
73 // Errors:
74 //      -
75 // Asserts:
76 //   theEmptyNodeList==0. No elements are in still in use.
77 //
78 ////////////////////////////////////////////////////////////////
79 //
80 // T& get();
81 // Description:
82 //   get's an element from the Pool.
83 // Parameters:
84 //   _
85 // Return value:
86 //   T& the element extracted from the Pool. (element must be cleared to
87 //   mimick newly created element)
88 // Errors:
89 //      -
90 // Asserts:
91 //   _
92 //
93 ////////////////////////////////////////////////////////////////
94 //
95 // void put(T& aT);
96 // Description:
97 //   Returns an element to the pool.
98 // Parameters:
99 //   aT The element to put back in the pool
100 // Return value:
101 //   void
102 // Errors:
103 //      -
104 // Asserts:
105 //   The pool has "empty" elements, to put element back in...
106 //
107 //===========================================================================
108 //
109 // .PRIVATE
110 //
111 //===========================================================================
112 
113 ////////////////////////////////////////////////////////////////
114 //
115 // void allocate(int aSize);
116 // Description:
117 //   add aSize elements to the pool
118 // Parameters:
119 //   aSize: # of elements to add to the pool
120 // Return value:
121 //   void
122 // Errors:
123 //      -
124 // Asserts:
125 //   _
126 //
127 ////////////////////////////////////////////////////////////////
128 //
129 // void deallocate();
130 // Description:
131 //   frees all elements kept in the pool.
132 // Parameters:
133 //   _
134 // Return value:
135 //   void
136 // Errors:
137 //      -
138 // Asserts:
139 //   No elements are "empty" i.e. in use.
140 //
141 //===========================================================================
142 //
143 // .PRIVATE
144 //
145 //===========================================================================
146 
147 ////////////////////////////////////////////////////////////////
148 //
149 // Pool<T>& operator=(const Pool<T>& cp);
150 // Description:
151 //   Prohibit use of assignement operator.
152 // Parameters:
153 //   cp
154 // Return value:
155 //   Pool<T>&
156 // Asserts:
157 //   _
158 //
159 ////////////////////////////////////////////////////////////////
160 //
161 // Pool(const Pool<T>& cp);
162 // Description:
163 //   Prohibit use of default copy constructor.
164 // Parameters:
165 //   cp
166 // Return value:
167 //   _
168 // Errors:
169 //      -
170 // Asserts:
171 //   _
172 //
173 ////////////////////////////////////////////////////////////////
174 //
175 // int initSize;
176 // Description: size of the initial size of the pool
177 //
178 ////////////////////////////////////////////////////////////////
179 //
180 // int incSize;
181 // Description: # of elements added to the pool when pool is exhausted.
182 //
183 ////////////////////////////////////////////////////////////////
184 //
185 // PoolElement<T>* theFullNodeList;
186 // Description: List to contain all "unused" elements in the pool
187 //
188 ////////////////////////////////////////////////////////////////
189 //
190 // PoolElement<T>* theEmptyNodeList;
191 // Description: List to contain all "in use" elements in the pool
192 //
193 //-------------------------------------------------------------------------
194 
195 template <class T>
196 class Pool
197 {
198 public:
199   enum { defInitSize = 256, defIncSize  = 64 };
200 
Pool(int anInitSize=defInitSize,int anIncSize=defIncSize)201   Pool(int anInitSize = defInitSize, int anIncSize = defIncSize) :
202     theIncSize(anIncSize),
203     theTop(0),
204     theCurrentSize(0),
205     theList(0)
206   {
207     allocate(anInitSize);
208   }
209 
~Pool(void)210   virtual ~Pool(void)
211   {
212     for (int i=0; i <theTop ; ++i)
213       delete theList[i];
214 
215     delete []theList;
216   }
217 
218   T* get();
219   void put(T* aT);
220 
221   // size() : Return number free items in pool
size()222   unsigned size(){ return theTop; }
223 
224   // inuse() : Return number items taken from pool
inuse() const225   unsigned inuse() const { return theCurrentSize - theTop; }
226 
227   const T* peekInuseItem(unsigned idx) const;
228 
229 protected:
allocate(int aSize)230   void allocate(int aSize)
231   {
232     T** tList = theList;
233     int i;
234     theList = new T*[aSize+theCurrentSize];
235     // allocate full list
236     for (i = 0; i < theTop; i++) {
237       theList[i] = tList[i];
238     }
239     delete []tList;
240     for (; (theTop < aSize); theTop++){
241       theList[theTop] = (T*)new T;
242     }
243     theCurrentSize += aSize;
244   }
245 
246 private:
247   Pool<T>& operator=(const Pool<T>& cp);
248   Pool(const Pool<T>& cp);
249 
250   int theIncSize;
251   int theTop;
252   int theCurrentSize;
253 
254   T** theList;
255 };
256 
257 //******************************************************************************
get()258 template <class T> inline T* Pool<T>::get()
259 {
260    T* tmp;
261    if( theTop == 0 )
262    {
263       allocate(theIncSize);
264    }
265    --theTop;
266    tmp = theList[theTop];
267    tmp->atGet();
268    return tmp;
269 }
270 
271 //
272 //******************************************************************************
put(T * aT)273 template <class T> inline void Pool<T>::put(T* aT)
274 {
275    theList[theTop]= aT;
276    ++theTop;
277 }
278 
peekInuseItem(unsigned idx) const279 template <class T> const T* Pool<T>::peekInuseItem(unsigned idx) const
280 {
281   assert(idx <= inuse());
282   // theTop is index of the first item in use
283   return theList[theTop + idx];
284 }
285 
286 
287 
288 
289 #undef JAM_FILE_ID
290 
291 #endif
292