Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef POOL_TYPE_HPP
00013 #define POOL_TYPE_HPP
00014
00015 #include "smallvec_type.hpp"
00016 #include "enum_type.hpp"
00017
00019 enum PoolType {
00020 PT_NONE = 0x00,
00021 PT_NORMAL = 0x01,
00022 PT_NCLIENT = 0x02,
00023 PT_NADMIN = 0x04,
00024 PT_DATA = 0x08,
00025 PT_ALL = 0x0F,
00026 };
00027 DECLARE_ENUM_AS_BIT_SET(PoolType)
00028
00029 typedef SmallVector<struct PoolBase *, 4> PoolVector;
00030
00032 struct PoolBase {
00033 const PoolType type;
00034
00039 static PoolVector *GetPools()
00040 {
00041 static PoolVector *pools = new PoolVector();
00042 return pools;
00043 }
00044
00045 static void Clean(PoolType);
00046
00051 PoolBase(PoolType pt) : type(pt)
00052 {
00053 *PoolBase::GetPools()->Append() = this;
00054 }
00055
00056 virtual ~PoolBase();
00057
00061 virtual void CleanPool() = 0;
00062
00063 private:
00068 PoolBase(const PoolBase &other);
00069 };
00070
00082 template <class Titem, typename Tindex, size_t Tgrowth_step, size_t Tmax_size, PoolType Tpool_type = PT_NORMAL, bool Tcache = false, bool Tzero = true>
00083 struct Pool : PoolBase {
00084 static const size_t MAX_SIZE = Tmax_size;
00085
00086 const char * const name;
00087
00088 size_t size;
00089 size_t first_free;
00090 size_t first_unused;
00091 size_t items;
00092 #ifdef OTTD_ASSERT
00093 size_t checked;
00094 #endif
00095 bool cleaning;
00096
00097 Titem **data;
00098
00099 Pool(const char *name);
00100 virtual void CleanPool();
00101
00108 inline Titem *Get(size_t index)
00109 {
00110 assert(index < this->first_unused);
00111 return this->data[index];
00112 }
00113
00119 inline bool IsValidID(size_t index)
00120 {
00121 return index < this->first_unused && this->Get(index) != NULL;
00122 }
00123
00129 inline bool CanAllocate(size_t n = 1)
00130 {
00131 bool ret = this->items <= Tmax_size - n;
00132 #ifdef OTTD_ASSERT
00133 this->checked = ret ? n : 0;
00134 #endif
00135 return ret;
00136 }
00137
00142 template <struct Pool<Titem, Tindex, Tgrowth_step, Tmax_size, Tpool_type, Tcache, Tzero> *Tpool>
00143 struct PoolItem {
00144 Tindex index;
00145
00152 inline void *operator new(size_t size)
00153 {
00154 return Tpool->GetNew(size);
00155 }
00156
00162 inline void operator delete(void *p)
00163 {
00164 if (p == NULL) return;
00165 Titem *pn = (Titem *)p;
00166 assert(pn == Tpool->Get(pn->index));
00167 Tpool->FreeItem(pn->index);
00168 }
00169
00178 inline void *operator new(size_t size, size_t index)
00179 {
00180 return Tpool->GetNew(size, index);
00181 }
00182
00191 inline void *operator new(size_t size, void *ptr)
00192 {
00193 for (size_t i = 0; i < Tpool->first_unused; i++) {
00194
00195
00196
00197
00198
00199
00200 assert(ptr != Tpool->data[i]);
00201 }
00202 return ptr;
00203 }
00204
00205
00213 static inline bool CanAllocateItem(size_t n = 1)
00214 {
00215 return Tpool->CanAllocate(n);
00216 }
00217
00222 static inline bool CleaningPool()
00223 {
00224 return Tpool->cleaning;
00225 }
00226
00232 static inline bool IsValidID(size_t index)
00233 {
00234 return Tpool->IsValidID(index);
00235 }
00236
00243 static inline Titem *Get(size_t index)
00244 {
00245 return Tpool->Get(index);
00246 }
00247
00254 static inline Titem *GetIfValid(size_t index)
00255 {
00256 return index < Tpool->first_unused ? Tpool->Get(index) : NULL;
00257 }
00258
00264 static inline size_t GetPoolSize()
00265 {
00266 return Tpool->first_unused;
00267 }
00268
00273 static inline size_t GetNumItems()
00274 {
00275 return Tpool->items;
00276 }
00277
00285 static inline void PostDestructor(size_t index) { }
00286 };
00287
00288 private:
00289 static const size_t NO_FREE_ITEM = MAX_UVALUE(size_t);
00290
00295 struct AllocCache {
00297 AllocCache *next;
00298 };
00299
00301 AllocCache *alloc_cache;
00302
00303 void *AllocateItem(size_t size, size_t index);
00304 void ResizeFor(size_t index);
00305 size_t FindFirstFree();
00306
00307 void *GetNew(size_t size);
00308 void *GetNew(size_t size, size_t index);
00309
00310 void FreeItem(size_t index);
00311 };
00312
00313 #define FOR_ALL_ITEMS_FROM(type, iter, var, start) \
00314 for (size_t iter = start; var = NULL, iter < type::GetPoolSize(); iter++) \
00315 if ((var = type::Get(iter)) != NULL)
00316
00317 #define FOR_ALL_ITEMS(type, iter, var) FOR_ALL_ITEMS_FROM(type, iter, var, 0)
00318
00319 #endif