/home/coin/SVN-release/CoinAll-1.1.0/Bcp/src/include/BCP_mempool.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 #ifndef _BCP_MEMPOOL_H
00004 #define _BCP_MEMPOOL_H
00005 
00006 // #define BCP_MEMPOOL_SAVE_BLOCKHEADS
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    // Create an allocator for objects of size n
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    // Allocate enough memory for one object;
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          // create the new block and save its head
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          // see if we can record another block head. If not, then resize
00042          // block_heads
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          // save the new block
00052          block_heads[block_num++] = block;
00053 #endif
00054          // link the entries in the new block together. skip the zeroth
00055          // element, that'll be returned to the caller.
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          // terminate the linked list with a null pointer
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    // Return to the pool the memory pointed to by p; 
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    // Deallocate all memory in the pool
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

Generated on Sun Nov 14 14:06:29 2010 for Coin-All by  doxygen 1.4.7