NCBI C++ ToolKit
obj_pool.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef CORELIB___OBJ_POOL__HPP
2 #define CORELIB___OBJ_POOL__HPP
3 
4 /* $Id: obj_pool.hpp 43554 2009-10-20 13:02:43Z ivanovp $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Author: Pavel Ivanov
30  * General purpose object pool.
31  */
32 
33 #include <corelib/ncbistd.hpp>
34 #include <corelib/ncbimtx.hpp>
35 #include <deque>
36 
38 
39 /** @addtogroup ResourcePool
40  *
41  * @{
42  */
43 
44 template <class TObjType> class CObjFactory_New;
45 
46 
47 /// General object pool
48 ///
49 /// @param TObjType
50 /// Type of objects in the pool (any type, not necessarily inherited from
51 /// CObject). Pool holds pointers to objects, so they shouldn't be copyable.
52 /// @param TObjFactory
53 /// Type of object factory, representing the policy of how objects created
54 /// and how they deleted. Factory should implement 2 methods -
55 /// CreateObject() and DeleteObject(). CreateObject() should get no
56 /// parameters, create new object and return pointer to it. Returned pointer
57 /// should be always non-NULL. DeleteObject() should take one parameter
58 /// (pointer to object) and should delete given object.
59 /// @param TLock
60 /// Type of the lock used in the pool to protect against multi-threading
61 /// issues. If no multi-threading protection is necessary CNoLock can be
62 /// used.
63 template <class TObjType,
64  class TObjFactory = CObjFactory_New<TObjType> >
65 class CObjPool
66 {
67 public:
68  typedef deque<TObjType*> TObjectsList;
69  /// Synonym to be able to use outside of the pool
70  typedef TObjType TObjectType;
71 
72  /// Create object pool
73  ///
74  /// @param max_storage_size
75  /// Maximum number of unused objects that can be stored in the pool.
76  /// Given default effectively means unlimited storage.
77  CObjPool(size_t max_storage_size = size_t(-1))
78  : m_MaxStorage(max_storage_size)
79  {}
80 
81  /// Create object pool
82  ///
83  /// @param factory
84  /// Object factory implementing creation/deletion strategy
85  /// @param max_storage_size
86  /// Maximum number of unused objects that can be stored in the pool.
87  /// Given default effectively means unlimited storage.
88  CObjPool(const TObjFactory& factory,
89  size_t max_storage_size = size_t(-1))
90  : m_MaxStorage(max_storage_size),
91  m_Factory(factory)
92  {}
93 
94  /// Destroy object pool and all objects it owns
95  ~CObjPool(void)
96  {
97  Clear();
98  }
99 
100  /// Get object from the pool, create if necessary
101  TObjType* Get(void)
102  {
103  TObjType* obj = NULL;
104 
105  m_ObjLock.Lock();
106  if (!m_FreeObjects.empty()) {
107  obj = m_FreeObjects.back();
108  m_FreeObjects.pop_back();
109  }
110  m_ObjLock.Unlock();
111 
112  if (obj == NULL) {
113  obj = m_Factory.CreateObject();
114  }
115 
116  _ASSERT(obj);
117  return obj;
118  }
119 
120  /// Return object to the pool for future use
121  void Return(TObjType* obj)
122  {
123  _ASSERT(obj);
124 
125  m_ObjLock.Lock();
126  if (m_FreeObjects.size() < m_MaxStorage) {
127  m_FreeObjects.push_back(obj);
128  obj = NULL;
129  }
130  m_ObjLock.Unlock();
131 
132  if (obj != NULL) {
133  m_Factory.DeleteObject(obj);
134  }
135  }
136 
137  /// Delete all objects returned to the pool so far and clean it
138  void Clear(void)
139  {
140  TObjectsList free_objects;
141 
142  m_ObjLock.Lock();
143  m_FreeObjects.swap(free_objects);
144  m_ObjLock.Unlock();
145 
146  ITERATE(typename TObjectsList, it, free_objects)
147  {
148  m_Factory.DeleteObject(*it);
149  }
150  }
151 
152  /// Get maximum number of unused objects that can be stored in the pool.
153  /// 0 means unlimited storage.
154  size_t GetMaxStorageSize(void) const
155  {
156  return m_MaxStorage;
157  }
158 
159  /// Set maximum number of unused objects that can be stored in the pool.
160  /// 0 means unlimited storage.
161  void SetMaxStorageSize(size_t max_storage_size)
162  {
163  // Writing of size_t is always an atomic operation
164  m_MaxStorage = max_storage_size;
165  }
166 
167 private:
170 
171  /// Maximum number of unused objects that can be stored in the pool
172  size_t m_MaxStorage;
173  /// Object factory
174  TObjFactory m_Factory;
175  /// Lock object to change the pool
177  /// List of unused objects
179 };
180 
181 
182 /// Guard that can be used to automatically return object to the pool after
183 /// leaving some scope. Guard can also be used to automatically acquire object
184 /// from pool and work after that as a smart pointer automatically converting
185 /// himself to the pointer to protected object. Guard can be used like this:
186 /// {{
187 /// TObjPoolGuard obj(pool);
188 /// obj->DoSomething();
189 /// FuncAcceptingPointerToObject(obj);
190 /// }}
191 ///
192 /// @param TObjPool
193 /// Type of the pool which this guard works with
194 ///
195 /// @sa CObjPool
196 template <class TObjPool>
198 {
199 public:
200  /// Type of object to protect
201  typedef typename TObjPool::TObjectType TObjType;
202 
203  /// Create guard and automatically acquire object from the pool
204  CObjPoolGuard(TObjPool& pool)
205  : m_Pool(pool),
206  m_Object(pool.Get())
207  {}
208 
209  /// Create guard to automatically return given object to the pool.
210  ///
211  /// @param pool
212  /// Pool to return object to
213  /// @param object
214  /// Object to protect. Parameter can be NULL, in this case no object is
215  /// acquired and protected on construction, but can be passed to the
216  /// guard later via Acquire().
217  CObjPoolGuard(TObjPool& pool, TObjType* object)
218  : m_Pool(pool),
219  m_Object(object)
220  {}
221 
223  {
224  Return();
225  }
226 
227  /// Get pointer to protected object
228  TObjType* GetObject(void) const
229  {
230  return m_Object;
231  }
232 
233  // Operators implementing smart-pointer-type conversions
234 
235  /// Automatic conversion to the pointer to protected object
236  operator TObjType* (void) const
237  {
238  return GetObject();
239  }
240  /// Automatic dereference to the protected object
241  TObjType& operator* (void) const
242  {
243  _ASSERT(m_Object);
244  return *GetObject();
245  }
246  /// Automatic dereference to the protected object
247  TObjType* operator-> (void) const
248  {
249  _ASSERT(m_Object);
250  return GetObject();
251  }
252 
253  /// Return protected object (if any) to the pool and acquire new object
254  /// for protection. If parameter is NULL then get object from the pool.
255  void Acquire(TObjType* object = NULL)
256  {
257  Return();
258  if (object) {
259  m_Object = object;
260  }
261  else {
262  m_Object = m_Pool.Get();
263  }
264  }
265 
266  /// Release protected object without returning it to the pool. After
267  /// calling to this method it is caller responsibility to return object
268  /// to the pool.
269  ///
270  /// @return
271  /// Object that was protected
273  {
274  TObjType* object = m_Object;
275  m_Object = NULL;
276  return object;
277  }
278 
279  /// Return protected object (if any) to the pool
280  void Return(void)
281  {
282  if (m_Object) {
283  m_Pool.Return(m_Object);
284  m_Object = NULL;
285  }
286  }
287 
288 private:
291 
292  /// Pool this guard is attached to
293  TObjPool& m_Pool;
294  /// Protected object
296 };
297 
298 
299 //////////////////////////////////////////////////////////////////////////
300 // Set of most frequently used object factories that can be used with
301 // CObjPool.
302 //////////////////////////////////////////////////////////////////////////
303 
304 /// Object factory for simple creation and deletion of the object
305 template <class TObjType>
307 {
308 public:
309  TObjType* CreateObject(void)
310  {
311  return new TObjType();
312  }
313 
314  void DeleteObject(TObjType* obj)
315  {
316  delete obj;
317  }
318 };
319 
320 /// Object factory for simple creation and deletion of the object with one
321 /// parameter passed to object's constructor.
322 template <class TObjType, class TParamType>
324 {
325 public:
326  /// @param param
327  /// Parameter value that will be passed to constructor of every new
328  /// object.
329  CObjFactory_NewParam(const TParamType& param)
330  : m_Param(param)
331  {}
332 
333  TObjType* CreateObject(void)
334  {
335  return new TObjType(m_Param);
336  }
337 
338  void DeleteObject(TObjType* obj)
339  {
340  delete obj;
341  }
342 
343 private:
344  /// Parameter value that will be passed to constructor of every new object
345  TParamType m_Param;
346 };
347 
348 /// Object factory for creation implemented by method of some class and
349 /// simple deletion.
350 template <class TObjType, class TMethodClass>
352 {
353 public:
354  typedef TObjType* (TMethodClass::*TMethod)(void);
355 
356  /// @param method_obj
357  /// Object which method will be called to create new object
358  /// @param method
359  /// Method to call to create new object
360  CObjFactory_NewMethod(TMethodClass* method_obj,
361  TMethod method)
362  : m_MethodObj(method_obj),
363  m_Method(method)
364  {}
365 
366  TObjType* CreateObject(void)
367  {
368  return (m_MethodObj->*m_Method)();
369  }
370 
371  void DeleteObject(TObjType* obj)
372  {
373  delete obj;
374  }
375 
376 private:
377  /// Object which method will be called to create new object
378  TMethodClass* m_MethodObj;
379  /// Method to call to create new object
381 };
382 
383 
384 /* @} */
385 
386 
388 
389 
390 #endif /* CORELIB___OBJ_POOL__HPP */
Object factory for creation implemented by method of some class and simple deletion.
Definition: obj_pool.hpp:352
Object factory for simple creation and deletion of the object with one parameter passed to object's c...
Definition: obj_pool.hpp:324
Object factory for simple creation and deletion of the object.
Definition: obj_pool.hpp:307
Guard that can be used to automatically return object to the pool after leaving some scope.
Definition: obj_pool.hpp:198
General object pool.
Definition: obj_pool.hpp:66
CSpinLock –.
Definition: ncbimtx.hpp:843
Include a standard set of the NCBI C++ Toolkit most basic headers.
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NULL
Definition: ncbistd.hpp:225
deque< TObjType * > TObjectsList
Definition: obj_pool.hpp:68
size_t GetMaxStorageSize(void) const
Get maximum number of unused objects that can be stored in the pool.
Definition: obj_pool.hpp:154
CObjPoolGuard & operator=(const CObjPoolGuard &)
TObjType * Release(void)
Release protected object without returning it to the pool.
Definition: obj_pool.hpp:272
CObjPoolGuard(TObjPool &pool)
Create guard and automatically acquire object from the pool.
Definition: obj_pool.hpp:204
void Acquire(TObjType *object=NULL)
Return protected object (if any) to the pool and acquire new object for protection.
Definition: obj_pool.hpp:255
TMethodClass * m_MethodObj
Object which method will be called to create new object.
Definition: obj_pool.hpp:378
CObjFactory_NewMethod(TMethodClass *method_obj, TMethod method)
Definition: obj_pool.hpp:360
TMethod m_Method
Method to call to create new object.
Definition: obj_pool.hpp:380
void Return(TObjType *obj)
Return object to the pool for future use.
Definition: obj_pool.hpp:121
~CObjPoolGuard(void)
Definition: obj_pool.hpp:222
TObjFactory m_Factory
Object factory.
Definition: obj_pool.hpp:174
TObjType * CreateObject(void)
Definition: obj_pool.hpp:366
TObjType * Get(void)
Get object from the pool, create if necessary.
Definition: obj_pool.hpp:101
void Return(void)
Return protected object (if any) to the pool.
Definition: obj_pool.hpp:280
TObjType * CreateObject(void)
Definition: obj_pool.hpp:309
TObjType *(TMethodClass::* TMethod)(void)
Definition: obj_pool.hpp:354
CObjPool(size_t max_storage_size=size_t(-1))
Create object pool.
Definition: obj_pool.hpp:77
void DeleteObject(TObjType *obj)
Definition: obj_pool.hpp:338
TObjType * GetObject(void) const
Get pointer to protected object.
Definition: obj_pool.hpp:228
TObjPool::TObjectType TObjType
Type of object to protect.
Definition: obj_pool.hpp:201
TObjType * m_Object
Protected object.
Definition: obj_pool.hpp:295
TObjType & operator*(void) const
Automatic dereference to the protected object.
Definition: obj_pool.hpp:241
CObjPoolGuard(const CObjPoolGuard &)
CObjPool(const TObjFactory &factory, size_t max_storage_size=size_t(-1))
Create object pool.
Definition: obj_pool.hpp:88
CSpinLock m_ObjLock
Lock object to change the pool.
Definition: obj_pool.hpp:176
TObjType * operator->(void) const
Automatic dereference to the protected object.
Definition: obj_pool.hpp:247
~CObjPool(void)
Destroy object pool and all objects it owns.
Definition: obj_pool.hpp:95
size_t m_MaxStorage
Maximum number of unused objects that can be stored in the pool.
Definition: obj_pool.hpp:172
CObjFactory_NewParam(const TParamType &param)
Definition: obj_pool.hpp:329
void Clear(void)
Delete all objects returned to the pool so far and clean it.
Definition: obj_pool.hpp:138
TObjPool & m_Pool
Pool this guard is attached to.
Definition: obj_pool.hpp:293
void SetMaxStorageSize(size_t max_storage_size)
Set maximum number of unused objects that can be stored in the pool.
Definition: obj_pool.hpp:161
CObjPoolGuard(TObjPool &pool, TObjType *object)
Create guard to automatically return given object to the pool.
Definition: obj_pool.hpp:217
TObjType * CreateObject(void)
Definition: obj_pool.hpp:333
void DeleteObject(TObjType *obj)
Definition: obj_pool.hpp:371
void DeleteObject(TObjType *obj)
Definition: obj_pool.hpp:314
TParamType m_Param
Parameter value that will be passed to constructor of every new object.
Definition: obj_pool.hpp:345
TObjType TObjectType
Synonym to be able to use outside of the pool.
Definition: obj_pool.hpp:70
CObjPool(const CObjPool &)
TObjectsList m_FreeObjects
List of unused objects.
Definition: obj_pool.hpp:178
CObjPool & operator=(const CObjPool &)
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
void Unlock(void)
Unlock the mutex.
Definition: ncbimtx.cpp:2342
void Lock(void)
Lock the mutex.
Definition: ncbimtx.cpp:2326
const TYPE & Get(const CNamedParameterList *param)
Multi-threading – mutexes; rw-locks; semaphore.
#define _ASSERT
Modified on Fri Sep 20 14:58:31 2024 by modify_doxy.py rev. 669887