Chemical Data Processing Library C++ API - Version 1.4.0
ObjectPool.hpp
Go to the documentation of this file.
1 /*
2  * ObjectPool.hpp
3  *
4  * This file is part of the Chemical Data Processing Toolkit
5  *
6  * Copyright (C) 2003 Thomas Seidel <thomas.seidel@univie.ac.at>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this library; see the file COPYING. If not, write to
20  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23 
29 #ifndef CDPL_UTIL_OBJECTPOOL_HPP
30 #define CDPL_UTIL_OBJECTPOOL_HPP
31 
32 #include <vector>
33 #include <cstddef>
34 #include <algorithm>
35 #include <new>
36 #include <memory>
37 #include <functional>
38 
39 
40 namespace CDPL
41 {
42 
43  namespace Util
44  {
45 
58  template <typename T>
59  class ObjectPool
60  {
61 
62  public:
66  typedef T ObjectType;
67 
71  typedef std::shared_ptr<ObjectType> SharedObjectPointer;
72 
76  typedef std::function<ObjectType*()> ConstructorFunction;
77 
81  typedef std::function<void(ObjectType*)> DestructorFunction;
82 
86  typedef std::function<void(ObjectType&)> ObjectFunction;
87 
92  {
93 
94  T* operator()() const
95  {
96  return new T();
97  }
98  };
99 
104  {
105 
106  void operator()(T* obj) const
107  {
108  delete obj;
109  }
110  };
111 
118  ObjectPool(const ObjectPool& pool):
119  maxSize(pool.maxSize), ctorFunc(pool.ctorFunc), dtorFunc(pool.dtorFunc),
120  initFunc(pool.initFunc), cleanFunc(pool.cleanFunc) {}
121 
126  ObjectPool(std::size_t max_size = 0):
127  maxSize(max_size), ctorFunc(DefaultConstructor()), dtorFunc(DefaultDestructor()) {}
128 
135  template <typename C, typename D>
136  ObjectPool(const C& ctor_func, const D& dtor_func, std::size_t max_size = 0):
137  maxSize(max_size), ctorFunc(ctor_func), dtorFunc(dtor_func)
138  {}
139 
146  {
147  std::for_each(pool.begin(), pool.end(), dtorFunc);
148  }
149 
161  {
162  ObjectType* obj;
163 
164  if (!pool.empty()) {
165  obj = pool.back();
166  pool.pop_back();
167 
168  } else {
169  obj = ctorFunc();
170 
171  if (!obj)
172  throw std::bad_alloc();
173  }
174 
175  SharedObjectPointer obj_ptr(obj, PutObject(*this));
176 
177  if (initFunc)
178  initFunc(*obj);
179 
180  return obj_ptr;
181  }
182 
187  std::size_t getSize() const
188  {
189  return pool.size();
190  }
191 
196  std::size_t getMaxSize() const
197  {
198  return maxSize;
199  }
200 
208  void setMaxSize(std::size_t max_size)
209  {
210  maxSize = max_size;
211 
212  shrinkToMaxSize();
213  }
214 
218  void freeMemory()
219  {
220  std::for_each(pool.begin(), pool.end(), dtorFunc);
221 
222  pool.clear();
223  }
224 
229  void setInitFunction(const ObjectFunction& func)
230  {
231  initFunc = func;
232  }
233 
239  {
240  cleanFunc = func;
241  }
242 
251  {
252  if (this == &pool)
253  return *this;
254 
255  maxSize = pool.maxSize;
256  ctorFunc = pool.ctorFunc;
257  dtorFunc = pool.dtorFunc;
258  initFunc = pool.initFunc;
259  cleanFunc = pool.cleanFunc;
260 
261  shrinkToMaxSize();
262 
263  return *this;
264  }
265 
266  private:
267  void shrinkToMaxSize()
268  {
269  if (maxSize == 0)
270  return;
271 
272  while (pool.size() > maxSize) {
273  dtorFunc(pool.back());
274  pool.pop_back();
275  }
276  }
277 
278  struct PutObject
279  {
280 
281  PutObject(ObjectPool& pool):
282  pool(pool) {}
283 
284  void operator()(ObjectType* obj) const
285  {
286  pool.put(obj);
287  }
288 
289  ObjectPool& pool;
290  };
291 
292  void put(ObjectType* obj)
293  {
294  if (maxSize > 0 && pool.size() >= maxSize) {
295  dtorFunc(obj);
296  return;
297  }
298 
299  try {
300  if (cleanFunc)
301  cleanFunc(*obj);
302 
303  pool.push_back(obj);
304 
305  } catch (...) {
306  dtorFunc(obj);
307  }
308  }
309 
310  typedef std::vector<ObjectType*> PooledObjectList;
311 
312  std::size_t maxSize;
313  PooledObjectList pool;
314  ConstructorFunction ctorFunc;
315  DestructorFunction dtorFunc;
316  ObjectFunction initFunc;
317  ObjectFunction cleanFunc;
318  };
319  } // namespace Util
320 } // namespace CDPL
321 
322 #endif // CDPL_UTIL_OBJECTPOOL_HPP
Data structure that caches instances of type T up to a user specified amount.
Definition: ObjectPool.hpp:60
std::size_t getSize() const
Returns the current number of idle objects in the pool.
Definition: ObjectPool.hpp:187
void setCleanupFunction(const ObjectFunction &func)
Sets the function to be invoked on an object when it is returned to the pool.
Definition: ObjectPool.hpp:238
std::shared_ptr< ObjectType > SharedObjectPointer
A smart pointer to a borrowed object that returns the object to the pool on destruction.
Definition: ObjectPool.hpp:71
void freeMemory()
Destroys all currently idle pool entries and releases their memory.
Definition: ObjectPool.hpp:218
std::function< void(ObjectType *)> DestructorFunction
Generic wrapper for functions destroying instances of ObjectType.
Definition: ObjectPool.hpp:81
ObjectPool(const C &ctor_func, const D &dtor_func, std::size_t max_size=0)
Constructs an ObjectPool instance using a user-supplied factory and destructor.
Definition: ObjectPool.hpp:136
SharedObjectPointer get()
Returns a smart pointer to a pool-owned object.
Definition: ObjectPool.hpp:160
std::function< ObjectType *()> ConstructorFunction
Generic wrapper for functions creating new instances of ObjectType.
Definition: ObjectPool.hpp:76
void setInitFunction(const ObjectFunction &func)
Sets the function to be invoked on an object when it is handed out by get().
Definition: ObjectPool.hpp:229
ObjectPool & operator=(const ObjectPool &pool)
Copy assignment operator.
Definition: ObjectPool.hpp:250
ObjectPool(const ObjectPool &pool)
Copy constructor.
Definition: ObjectPool.hpp:118
ObjectPool(std::size_t max_size=0)
Constructs a default-configured ObjectPool instance using DefaultConstructor and DefaultDestructor.
Definition: ObjectPool.hpp:126
void setMaxSize(std::size_t max_size)
Sets the maximum pool size.
Definition: ObjectPool.hpp:208
std::size_t getMaxSize() const
Returns the currently configured maximum pool size.
Definition: ObjectPool.hpp:196
~ObjectPool()
Destructor. Destroys all currently idle pool entries.
Definition: ObjectPool.hpp:145
std::function< void(ObjectType &)> ObjectFunction
Generic wrapper for functions operating on instances of ObjectType.
Definition: ObjectPool.hpp:86
T ObjectType
The type of the pooled objects.
Definition: ObjectPool.hpp:66
constexpr unsigned int D
Specifies Hydrogen (Deuterium).
Definition: AtomType.hpp:62
constexpr unsigned int T
Specifies Hydrogen (Tritium).
Definition: AtomType.hpp:67
constexpr unsigned int C
Specifies Carbon.
Definition: AtomType.hpp:92
The namespace of the Chemical Data Processing Library.
Default object factory which creates new instances of ObjectType via new.
Definition: ObjectPool.hpp:92
T * operator()() const
Definition: ObjectPool.hpp:94
Default object destructor which destroys instances of ObjectType via delete.
Definition: ObjectPool.hpp:104
void operator()(T *obj) const
Definition: ObjectPool.hpp:106