/******************************************************************** created: 2008/06/23 created: 23:6:2008 10:27 filename: d:\Projects\ServiceSpace\ServiceSpace\ServiceSpaceLib\block_pool.h file path: d:\Projects\ServiceSpace\ServiceSpace\ServiceSpaceLib file base: block_pool file ext: h author: purpose: *********************************************************************/ #ifndef __UTILIB_BLOCK_H__ #define __UTILIB_BLOCK_H__ #include #include #include "noncopyable.h" #include "pool_lock.h" namespace utilib { template struct block { enum { Size = Bytes }; char buf[Size]; block * next; }; template struct block { enum { Size = Bytes }; char buf[Size]; block * next; block() { memset(buf, 0, sizeof(buf)); } }; template struct chunk { typedef Block block_type; block_type blocks[Count]; chunk * next; chunk() { for (size_t i = 0; i < Count - 1; ++i) blocks[i].next = &blocks[i + 1]; blocks[Count - 1].next = 0; next = 0; } }; namespace grow { template struct arithmetic { arithmetic() : count_(0) { } size_t operator()() { return count_ += Diff; } size_t count_; }; } // namespace grow template< size_t Bytes, size_t Count = 50, class Grow = grow::arithmetic<1>, class Lock = pool_lock, bool ClearZero = false > class block_pool : public noncopyable { public: typedef Grow grow_type; typedef block block_type; typedef chunk chunk_type; typedef Lock lock_type; block_pool() : chunk_(0), block_(0) { grow(); } ~block_pool() { clean(); } void * allocate() { pool_guard guard(lock_); if (!block_) this->grow_i(); block_type * p = block_; block_ = p->next; return p->buf; } void deallocate(void * p) { if (!p) return; pool_guard guard(lock_); block_type * tmp = (block_type *)p; tmp->next = block_; block_ = tmp; } void grow() { pool_guard guard(lock_); grow_i(); } void clean() { pool_guard guard(lock_); clean_i(); } size_t max_size()const { return 1; } private: void grow_i() { size_t chunks = grow_(); size_t i = 0; for(; i < chunks; ++i) { chunk_type * p = new chunk_type(); if (!p) throw std::bad_alloc(); p->next = chunk_; p->blocks[Count - 1].next = block_; block_ = &p->blocks[0]; chunk_ =p; } } void clean_i() { while(chunk_) { chunk_type * tmp = chunk_; chunk_ = tmp->next; delete tmp; } chunk_ = 0; block_ = 0; } chunk_type * chunk_; block_type * block_; grow_type grow_; lock_type lock_; }; } #endif