structpool.h

Go to the documentation of this file.
00001 #ifndef structpool_h
00002 #define structpool_h
00003 
00004 // same as ../nrncvode/pool.h but items do not require a clear method.
00005 
00006 // create and manage a vector of objects as a memory pool of those objects
00007 // the object must have a void clear() method which takes care of any 
00008 // data the object contains which should be deleted upon free_all.
00009 // clear() is NOT called on free, only on free_all.
00010 
00011 // the chain of Pool
00012 // is only for extra items in a pool_ and no other fields are used.
00013 // the pool doubles in size every time a chain Pool is added.
00014 // maxget() tells the most number of pool items used at once.
00015 
00016 #define declareStructPool(Pool,T) \
00017 class Pool { \
00018 public: \
00019    Pool(long count); \
00020    ~Pool(); \
00021    T* alloc(); \
00022    void hpfree(T*); \
00023    int maxget() { return maxget_;} \
00024    void free_all(); \
00025 private: \
00026    void grow(); \
00027 private: \
00028    T** items_; \
00029    T* pool_; \
00030    long pool_size_; \
00031    long count_; \
00032    long get_; \
00033    long put_; \
00034    long nget_; \
00035    long maxget_; \
00036    Pool* chain_; \
00037 }; \
00038  \
00039 
00040 #define implementStructPool(Pool,T) \
00041 Pool::Pool(long count) { \
00042    count_ = count; \
00043    pool_ = new T[count_]; \
00044    pool_size_ = count; \
00045    items_ = new T*[count_]; \
00046    for (long i = 0; i < count_; ++i) items_[i] = pool_ + i; \
00047    get_ = 0; \
00048    put_ = 0; \
00049    nget_ = 0; \
00050    maxget_ = 0; \
00051    chain_ = 0; \
00052 } \
00053  \
00054 void Pool::grow() { \
00055    assert(get_ == put_); \
00056    Pool* p = new Pool(count_); \
00057    p->chain_ = chain_; \
00058    chain_ = p; \
00059    long newcnt = 2*count_; \
00060    T** itms = new T*[newcnt]; \
00061    long i, j; \
00062    put_ += count_; \
00063    for (i = 0; i < get_; ++i) { \
00064       itms[i] = items_[i]; \
00065    } \
00066    for (i = get_, j = 0; j < count_; ++i, ++j) { \
00067       itms[i] = p->items_[j]; \
00068    } \
00069    for (i = put_, j = get_; j < count_; ++i, ++j) { \
00070       itms[i] = items_[j]; \
00071    } \
00072    delete [] items_; \
00073    delete [] p->items_; \
00074    p->items_ = 0; \
00075    items_ = itms; \
00076    count_ = newcnt; \
00077 } \
00078  \
00079 Pool::~Pool() { \
00080    if (chain_) { \
00081       delete chain_; \
00082    } \
00083    delete [] pool_; \
00084    if (items_) { \
00085       delete [] items_; \
00086    } \
00087 } \
00088  \
00089 T* Pool::alloc() { \
00090    if (nget_ >= count_) { grow(); } \
00091    T* item = items_[get_]; \
00092    get_ = (get_+1)%count_; \
00093    ++nget_; \
00094    if (nget_ > maxget_) { maxget_ = nget_; } \
00095    return item; \
00096 } \
00097  \
00098 void Pool::hpfree(T* item) { \
00099    assert(nget_ > 0); \
00100    items_[put_] = item; \
00101    put_ = (put_ + 1)%count_; \
00102    --nget_; \
00103 } \
00104 \
00105 void Pool::free_all() { \
00106    Pool* pp; \
00107    long i; \
00108    nget_ = 0; \
00109    get_ = 0; \
00110    put_ = 0; \
00111    for(pp = this; pp; pp = pp->chain_) { \
00112       for (i=0; i < pp->pool_size_; ++i) { \
00113          items_[put_++] = pp->pool_ + i; \
00114       } \
00115    } \
00116    assert(put_ == count_); \
00117    put_ = 0; \
00118 } \
00119 \
00120 
00121 #endif
Generated on Mon Jun 13 08:10:26 2011 for NEURON by  doxygen 1.6.3