00001
00002
00003 #ifndef _BCP_MEMPOOL_H
00004 #define _BCP_MEMPOOL_H
00005
00006
00007
00008 class BCP_MemPool {
00009 private:
00010 const size_t BLOCK_SIZE;
00011 size_t entry_size;
00012 void ** first_free;
00013 #ifdef BCP_MEMPOOL_SAVE_BLOCKHEADS
00014 void *** block_heads;
00015 size_t block_num;
00016 size_t max_block_num;
00017 #endif
00018 public:
00019
00020 BCP_MemPool(const size_t n, const size_t bl_size = 1023) :
00021 BLOCK_SIZE(bl_size), entry_size(n), first_free(0)
00022 #ifdef BCP_MEMPOOL_SAVE_BLOCKHEADS
00023 , block_heads(0), block_num(0), max_block_num(0)
00024 #endif
00025 {}
00026
00027
00028 inline void * alloc(size_t n) {
00029 if (n != entry_size)
00030 return ::operator new(n);
00031 void ** p = first_free;
00032 if (p) {
00033 first_free = static_cast<void **>(*p);
00034 } else {
00035
00036 const size_t ptr_in_entry = entry_size/sizeof(void**) +
00037 ((entry_size % sizeof(void **)) == 0 ? 0 : 1);
00038 const size_t dist = ptr_in_entry * sizeof(void **);
00039 void ** block = static_cast<void**>(::operator new(BLOCK_SIZE*dist));
00040 #ifdef BCP_MEMPOOL_SAVE_BLOCKHEADS
00041
00042
00043 if (max_block_num == block_num) {
00044 max_block_num = 1.2 * block_num + 10;
00045 const void *** old_block_heads = block_heads;
00046 block_heads = static_cast<void ***>(::operator new(max_block_num));
00047 for (size_t i = 0; i < block_num; ++i)
00048 block_heads[i] = old_block_heads[i];
00049 ::operator delete(old_block_heads);
00050 }
00051
00052 block_heads[block_num++] = block;
00053 #endif
00054
00055
00056 for (size_t i = 1; i < BLOCK_SIZE-1; ++i)
00057 block[i*ptr_in_entry] =
00058 static_cast<void*>(block + ((i+1)*ptr_in_entry));
00059
00060 block[(BLOCK_SIZE-1)*ptr_in_entry] = 0;
00061 p = block;
00062 first_free = block + ptr_in_entry;
00063 }
00064 return static_cast<void*>(p);
00065 }
00066
00067
00068 inline void free(void *p, size_t n) {
00069 if (p == 0) return;
00070 if (n != entry_size) {
00071 ::operator delete(p);
00072 return;
00073 }
00074 void** pp = static_cast<void**>(p);
00075 *pp = static_cast<void*>(first_free);
00076 first_free = pp;
00077 }
00078
00079 ~BCP_MemPool() {
00080 #ifdef BCP_MEMPOOL_SAVE_BLOCKHEADS
00081 for (size_t i = 0; i < block_num; ++i) {
00082 ::operator delete(block_heads[i]);
00083 }
00084 ::operator delete(block_heads);
00085 #endif
00086 }
00087 };
00088
00089 #endif