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
00075 template <class Titem, typename Tindex, size_t Tgrowth_step, size_t Tmax_size, PoolType Tpool_type = PT_NORMAL, bool Tcache = false, bool Tzero = true>
00076 struct Pool : PoolBase {
00077 static const size_t MAX_SIZE = Tmax_size;
00078
00079 const char * const name;
00080
00081 size_t size;
00082 size_t first_free;
00083 size_t first_unused;
00084 size_t items;
00085 #ifdef OTTD_ASSERT
00086 size_t checked;
00087 #endif
00088 bool cleaning;
00089
00090 Titem **data;
00091
00092 Pool(const char *name);
00093 virtual void CleanPool();
00094
00101 inline Titem *Get(size_t index)
00102 {
00103 assert(index < this->first_unused);
00104 return this->data[index];
00105 }
00106
00112 inline bool IsValidID(size_t index)
00113 {
00114 return index < this->first_unused && this->Get(index) != NULL;
00115 }
00116
00122 inline bool CanAllocate(size_t n = 1)
00123 {
00124 bool ret = this->items <= Tmax_size - n;
00125 #ifdef OTTD_ASSERT
00126 this->checked = ret ? n : 0;
00127 #endif
00128 return ret;
00129 }
00130
00135 template <struct Pool<Titem, Tindex, Tgrowth_step, Tmax_size, Tpool_type, Tcache, Tzero> *Tpool>
00136 struct PoolItem {
00137 Tindex index;
00138
00145 inline void *operator new(size_t size)
00146 {
00147 return Tpool->GetNew(size);
00148 }
00149
00155 inline void operator delete(void *p)
00156 {
00157 Titem *pn = (Titem *)p;
00158 assert(pn == Tpool->Get(pn->index));
00159 Tpool->FreeItem(pn->index);
00160 }
00161
00170 inline void *operator new(size_t size, size_t index)
00171 {
00172 return Tpool->GetNew(size, index);
00173 }
00174
00183 inline void *operator new(size_t size, void *ptr)
00184 {
00185 for (size_t i = 0; i < Tpool->first_unused; i++) {
00186
00187
00188
00189
00190
00191
00192 assert(ptr != Tpool->data[i]);
00193 }
00194 return ptr;
00195 }
00196
00197
00205 static inline bool CanAllocateItem(size_t n = 1)
00206 {
00207 return Tpool->CanAllocate(n);
00208 }
00209
00214 static inline bool CleaningPool()
00215 {
00216 return Tpool->cleaning;
00217 }
00218
00224 static inline bool IsValidID(size_t index)
00225 {
00226 return Tpool->IsValidID(index);
00227 }
00228
00235 static inline Titem *Get(size_t index)
00236 {
00237 return Tpool->Get(index);
00238 }
00239
00246 static inline Titem *GetIfValid(size_t index)
00247 {
00248 return index < Tpool->first_unused ? Tpool->Get(index) : NULL;
00249 }
00250
00256 static inline size_t GetPoolSize()
00257 {
00258 return Tpool->first_unused;
00259 }
00260
00265 static inline size_t GetNumItems()
00266 {
00267 return Tpool->items;
00268 }
00269
00277 static inline void PostDestructor(size_t index) { }
00278 };
00279
00280 private:
00281 static const size_t NO_FREE_ITEM = MAX_UVALUE(size_t);
00282
00287 struct AllocCache {
00289 AllocCache *next;
00290 };
00291
00293 AllocCache *alloc_cache;
00294
00295 void *AllocateItem(size_t size, size_t index);
00296 void ResizeFor(size_t index);
00297 size_t FindFirstFree();
00298
00299 void *GetNew(size_t size);
00300 void *GetNew(size_t size, size_t index);
00301
00302 void FreeItem(size_t index);
00303 };
00304
00305 #define FOR_ALL_ITEMS_FROM(type, iter, var, start) \
00306 for (size_t iter = start; var = NULL, iter < type::GetPoolSize(); iter++) \
00307 if ((var = type::Get(iter)) != NULL)
00308
00309 #define FOR_ALL_ITEMS(type, iter, var) FOR_ALL_ITEMS_FROM(type, iter, var, 0)
00310
00311 #endif