pool.h

00001 /*
00002  * pool.h
00003  * This file is part of dbPager Classes Library (DCL)
00004  *
00005  * Copyright (c) 2008 Dennis Prochko <wolfsoft@mail.ru>
00006  *
00007  * DCL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation version 3.
00010  *
00011  * DCL is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with DCL; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor,
00019  * Boston, MA  02110-1301  USA
00020  */
00021 
00022 #ifndef _POOL_H_
00023 #define _POOL_H_
00024 
00025 #include <algorithm>
00026 #include <queue>
00027 #include <map>
00028 
00029 #include <dcl/mutex.h>
00030 #include <dcl/noncopyable.h>
00031 
00032 namespace dbp {
00033 
00034 template <class T>
00035 class pool_ptr;
00036 
00038 
00047 template <class T>
00048 class pool: public noncopyable {
00049         friend class pool_ptr<T>;
00050 public:
00052         virtual ~pool() {
00053                 std::for_each(_all.begin(), _all.end(), delete_item);
00054         }
00056 
00062         pool_ptr<T> acquire(const std::string &key = std::string("")) {
00063                 return pool_ptr<T>(acquire_item(key), this, key);
00064         }
00066         int size() const {
00067                 return _all.size();
00068         }
00070         int in_use() const {
00071                 int total = 0;
00072                 for (queue_idx_iterator it = _free.begin();
00073                   it != _free.end(); ++it) {
00074                         total += it->second.size();
00075                 }
00076                 return _all.size() - total;
00077         }
00078 private:
00079         typedef std::map<std::string, std::queue<T*> > queue_idx;
00080         typedef typename queue_idx::const_iterator queue_idx_iterator;
00081         queue_idx _free;
00082         std::vector<T*> _all;
00083         mutex cs;
00084         T* acquire_item(const std::string &key) {
00085                 mutex_guard guard(cs);
00086                 std::queue<T*> &q = _free[key];
00087                 if (q.empty()) {
00088                         T *item = new T();
00089                         _all.push_back(item);
00090                         return item;
00091                 }
00092                 T *item = q.front();
00093                 q.pop();
00094                 return item;
00095         }
00096         void release_item(T *item, const std::string &key) {
00097                 mutex_guard guard(cs);
00098                 std::queue<T*> &q = _free[key];
00099                 q.push(item);
00100         }
00101         static void delete_item(T *item) {
00102                 delete item;
00103         }
00104 };
00105 
00107 
00113 template <class T>
00114 class pool_ptr {
00115         friend class pool<T>;
00116 public:
00118         ~pool_ptr() {
00119                 if (_main) {
00120                         _pool->release_item(_item, _key);
00121                 }
00122         }
00123         pool_ptr(const pool_ptr<T> &src): _item(src._item), _pool(src._pool),
00124           _key(src._key), _main(src._main) {
00125                 const_cast<pool_ptr<T>&>(src)._main = false;
00126         }
00128         const pool_ptr<T>& operator=(const pool_ptr<T> &src) {
00129                 _item = src._item;
00130                 _pool = src._pool;
00131                 _key = src._key;
00132                 _main = true;
00133                 const_cast<pool_ptr<T>&>(src)._main = false;
00134         }
00136         T& operator*() const {
00137                 return *_item;
00138         }
00140         T* operator->() const {
00141                 return _item;
00142         }
00143 private:
00144         T *_item;
00145         pool<T> *_pool;
00146         const std::string _key;
00147         bool _main;
00148         pool_ptr() { }
00149         pool_ptr(T *item, pool<T> *pool, const std::string &key): _item(item),
00150           _pool(pool), _key(key), _main(true) { }
00151 };
00152 
00153 }
00154 
00155 #endif /*_POOL_H_*/
00156 

 
Support This Project
SourceForge.net Logo