pool.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00156