00001
00029 #ifndef _POOL_H
00030 #define _POOL_H
00031
00032 #include <cassert>
00033 #include <map>
00034
00035 namespace ace {
00036
00038
00043 template<class _Type>
00044 class MemoryBlock {
00047 const size_t _unit_size;
00051 _Type *_memory;
00055 _Type *_free;
00059 _Type *_upper_bound;
00060
00061 protected:
00062
00065 MemoryBlock<_Type>(const MemoryBlock<_Type>& mpb);
00068 MemoryBlock<_Type>& operator=(const MemoryBlock<_Type>& mpb);
00069
00070 public:
00077 MemoryBlock(size_t block_size): _unit_size(sizeof(_Type)), _memory(NULL), _free(NULL), _upper_bound(NULL) {
00078 _free = _memory = static_cast<_Type *>(operator new(block_size*_unit_size));
00079 _upper_bound = _memory + block_size;
00080 }
00083 virtual ~MemoryBlock(void) throw() {
00084 operator delete(_memory);
00085 }
00088 inline _Type * assigned_mem_bound(void) const throw() { return _free; }
00091 inline size_t count_free_memory(void) const throw() { return (_free != NULL) ? (_upper_bound - _free) : 0; }
00094 inline bool is_full(void) const throw() { return ( (_memory != NULL) && (_free == _upper_bound) ); }
00101 _Type * get_memory(size_t mem_size = 1) throw() {
00102 if ( (_memory == NULL) || (count_free_memory() < mem_size) ) {
00103
00104 return NULL;
00105 }
00106 _Type *alloc = _free;
00107
00108 _free += mem_size;
00109 return alloc;
00110 }
00113 inline _Type * lower_bound(void) const throw() { return _memory; }
00116 inline _Type * upper_bound(void) const throw() { return _upper_bound; }
00119 inline size_t unit_size(void) const throw() { return _unit_size; }
00120 };
00121
00122
00128 template<class _Type, template<typename _Type> class _Block>
00129 class MemoryPool {
00132 size_t _block_size;
00133
00134 protected:
00135
00138 virtual _Block<_Type> * create_new_block(void) = 0;
00139
00140 public:
00144 MemoryPool(size_t block_size) throw(): _block_size(block_size) {}
00147 virtual ~MemoryPool(void) throw() {}
00150 inline size_t block_size(void) const throw() { return _block_size; }
00153 virtual void clear(void) throw() = 0;
00160 virtual _Type * get_memory(size_t mem_size) = 0;
00161 };
00162
00163
00170 template<class _Type>
00171 class RandomSizedMemoryPool: public MemoryPool<_Type, MemoryBlock> {
00172 protected:
00175 typedef MemoryBlock<_Type> _block_type;
00176
00177
00181 typedef typename std::multimap<size_t, _block_type *> _blocks_free_sizes_map;
00184 _block_type *_recently_used_block;
00187 _blocks_free_sizes_map _mem_blocks;
00188
00189 protected:
00194 virtual _block_type * create_new_block(void) {
00195
00196 return new _block_type(this->block_size());
00197 }
00198
00199 public:
00203 RandomSizedMemoryPool(size_t block_size) throw(): MemoryPool<_Type, MemoryBlock>(block_size), _recently_used_block(NULL), _mem_blocks() {}
00206 virtual ~RandomSizedMemoryPool(void) throw() {
00207 this->clear();
00208 }
00212 virtual void clear(void) throw() {
00213
00214 for ( typename _blocks_free_sizes_map::iterator i_pool = _mem_blocks.begin(); i_pool != _mem_blocks.end(); ++i_pool ) {
00215 delete i_pool->second;
00216 }
00217
00218 _mem_blocks.clear();
00219 }
00228 virtual _Type * get_memory(size_t mem_size) {
00229
00230 if ( mem_size > this->block_size() ) {
00231
00232 return NULL;
00233 }
00234
00235 _block_type *mb = NULL;
00236
00237
00238 if ( _recently_used_block == NULL ) {
00239
00240 mb = _recently_used_block = this->create_new_block();
00241 } else if ( mem_size <= _recently_used_block->count_free_memory() ) {
00242
00243 mb = _recently_used_block;
00244 } else {
00245
00246 if ( !_mem_blocks.empty() && (mem_size <= _mem_blocks.rbegin()->first) ) {
00247
00248
00249 typename _blocks_free_sizes_map::iterator i_pools = _mem_blocks.lower_bound(mem_size);
00250
00251 assert(i_pools != _mem_blocks.end());
00252
00253 mb = i_pools->second;
00254
00255 _mem_blocks.erase(i_pools);
00256 } else {
00257
00258
00259 mb = create_new_block();
00260 }
00261
00262
00263 _mem_blocks.insert(typename _blocks_free_sizes_map::value_type(_recently_used_block->count_free_memory(), _recently_used_block));
00264
00265 _recently_used_block = mb;
00266 }
00267
00268 return mb->get_memory(mem_size);
00269 }
00270 };
00271
00275 class VoidPool: public RandomSizedMemoryPool<char> {
00276 public:
00280 VoidPool(size_t block_size) throw(): RandomSizedMemoryPool<char>(block_size) {}
00283 virtual ~VoidPool(void) throw() {}
00284
00292 virtual void * get_raw_memory(size_t mem_size) {
00293 return this->get_memory(mem_size);
00294 }
00295
00296 };
00297
00298 }
00299
00300 #endif