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 
98  T* operator()() const
99  {
100  return new T();
101  }
102  };
103 
108  {
109 
114  void operator()(T* obj) const
115  {
116  delete obj;
117  }
118  };
119 
126  ObjectPool(const ObjectPool& pool):
127  maxSize(pool.maxSize), ctorFunc(pool.ctorFunc), dtorFunc(pool.dtorFunc),
128  initFunc(pool.initFunc), cleanFunc(pool.cleanFunc) {}
129 
134  ObjectPool(std::size_t max_size = 0):
135  maxSize(max_size), ctorFunc(DefaultConstructor()), dtorFunc(DefaultDestructor()) {}
136 
143  template <typename C, typename D>
144  ObjectPool(const C& ctor_func, const D& dtor_func, std::size_t max_size = 0):
145  maxSize(max_size), ctorFunc(ctor_func), dtorFunc(dtor_func)
146  {}
147 
154  {
155  std::for_each(pool.begin(), pool.end(), dtorFunc);
156  }
157 
169  {
170  ObjectType* obj;
171 
172  if (!pool.empty()) {
173  obj = pool.back();
174  pool.pop_back();
175 
176  } else {
177  obj = ctorFunc();
178 
179  if (!obj)
180  throw std::bad_alloc();
181  }
182 
183  SharedObjectPointer obj_ptr(obj, PutObject(*this));
184 
185  if (initFunc)
186  initFunc(*obj);
187 
188  return obj_ptr;
189  }
190 
195  std::size_t getSize() const
196  {
197  return pool.size();
198  }
199 
204  std::size_t getMaxSize() const
205  {
206  return maxSize;
207  }
208 
216  void setMaxSize(std::size_t max_size)
217  {
218  maxSize = max_size;
219 
220  shrinkToMaxSize();
221  }
222 
226  void freeMemory()
227  {
228  std::for_each(pool.begin(), pool.end(), dtorFunc);
229 
230  pool.clear();
231  }
232 
237  void setInitFunction(const ObjectFunction& func)
238  {
239  initFunc = func;
240  }
241 
247  {
248  cleanFunc = func;
249  }
250 
259  {
260  if (this == &pool)
261  return *this;
262 
263  maxSize = pool.maxSize;
264  ctorFunc = pool.ctorFunc;
265  dtorFunc = pool.dtorFunc;
266  initFunc = pool.initFunc;
267  cleanFunc = pool.cleanFunc;
268 
269  shrinkToMaxSize();
270 
271  return *this;
272  }
273 
274  private:
275  void shrinkToMaxSize()
276  {
277  if (maxSize == 0)
278  return;
279 
280  while (pool.size() > maxSize) {
281  dtorFunc(pool.back());
282  pool.pop_back();
283  }
284  }
285 
286  struct PutObject
287  {
288 
289  PutObject(ObjectPool& pool):
290  pool(pool) {}
291 
292  void operator()(ObjectType* obj) const
293  {
294  pool.put(obj);
295  }
296 
297  ObjectPool& pool;
298  };
299 
300  void put(ObjectType* obj)
301  {
302  if (maxSize > 0 && pool.size() >= maxSize) {
303  dtorFunc(obj);
304  return;
305  }
306 
307  try {
308  if (cleanFunc)
309  cleanFunc(*obj);
310 
311  pool.push_back(obj);
312 
313  } catch (...) {
314  dtorFunc(obj);
315  }
316  }
317 
318  typedef std::vector<ObjectType*> PooledObjectList;
319 
320  std::size_t maxSize;
321  PooledObjectList pool;
322  ConstructorFunction ctorFunc;
323  DestructorFunction dtorFunc;
324  ObjectFunction initFunc;
325  ObjectFunction cleanFunc;
326  };
327  } // namespace Util
328 } // namespace CDPL
329 
330 #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:195
void setCleanupFunction(const ObjectFunction &func)
Sets the function to be invoked on an object when it is returned to the pool.
Definition: ObjectPool.hpp:246
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:226
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:144
SharedObjectPointer get()
Returns a smart pointer to a pool-owned object.
Definition: ObjectPool.hpp:168
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:237
ObjectPool & operator=(const ObjectPool &pool)
Copy assignment operator.
Definition: ObjectPool.hpp:258
ObjectPool(const ObjectPool &pool)
Copy constructor.
Definition: ObjectPool.hpp:126
ObjectPool(std::size_t max_size=0)
Constructs a default-configured ObjectPool instance using DefaultConstructor and DefaultDestructor.
Definition: ObjectPool.hpp:134
void setMaxSize(std::size_t max_size)
Sets the maximum pool size.
Definition: ObjectPool.hpp:216
std::size_t getMaxSize() const
Returns the currently configured maximum pool size.
Definition: ObjectPool.hpp:204
~ObjectPool()
Destructor. Destroys all currently idle pool entries.
Definition: ObjectPool.hpp:153
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
Creates a new instance of ObjectType via new.
Definition: ObjectPool.hpp:98
Default object destructor which destroys instances of ObjectType via delete.
Definition: ObjectPool.hpp:108
void operator()(T *obj) const
Destroys the instance pointed to by obj via delete.
Definition: ObjectPool.hpp:114