pool_type.hpp

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #ifndef POOL_TYPE_HPP
00013 #define POOL_TYPE_HPP
00014 
00025 template <class Titem, typename Tindex, size_t Tgrowth_step, size_t Tmax_size, bool Tcache = false, bool Tzero = true>
00026 struct Pool {
00027   static const size_t MAX_SIZE = Tmax_size; 
00028 
00029   const char * const name; 
00030 
00031   size_t size;         
00032   size_t first_free;   
00033   size_t first_unused; 
00034   size_t items;        
00035   bool cleaning;       
00036 
00037   Titem **data;        
00038 
00039   Pool(const char *name);
00040   void CleanPool();
00041 
00048   FORCEINLINE Titem *Get(size_t index)
00049   {
00050     assert(index < this->first_unused);
00051     return this->data[index];
00052   }
00053 
00059   FORCEINLINE bool IsValidID(size_t index)
00060   {
00061     return index < this->first_unused && this->Get(index) != NULL;
00062   }
00063 
00069   FORCEINLINE bool CanAllocate(size_t n = 1)
00070   {
00071     return this->items <= Tmax_size - n;
00072   }
00073 
00078   template <struct Pool<Titem, Tindex, Tgrowth_step, Tmax_size, Tcache, Tzero> *Tpool>
00079   struct PoolItem {
00080     Tindex index; 
00081 
00088     FORCEINLINE void *operator new(size_t size)
00089     {
00090       return Tpool->GetNew(size);
00091     }
00092 
00098     FORCEINLINE void operator delete(void *p)
00099     {
00100       Titem *pn = (Titem *)p;
00101       assert(pn == Tpool->Get(pn->index));
00102       Tpool->FreeItem(pn->index);
00103     }
00104 
00113     FORCEINLINE void *operator new(size_t size, size_t index)
00114     {
00115       return Tpool->GetNew(size, index);
00116     }
00117 
00126     FORCEINLINE void *operator new(size_t size, void *ptr)
00127     {
00128       for (size_t i = 0; i < Tpool->first_unused; i++) {
00129         /* Don't allow creating new objects over existing.
00130          * Even if we called the destructor and reused this memory,
00131          * we don't know whether 'size' and size of currently allocated
00132          * memory are the same (because of possible inheritance).
00133          * Use { size_t index = item->index; delete item; new (index) item; }
00134          * instead to make sure destructor is called and no memory leaks. */
00135         assert(ptr != Tpool->data[i]);
00136       }
00137       return ptr;
00138     }
00139 
00140 
00148     static FORCEINLINE bool CanAllocateItem(size_t n = 1)
00149     {
00150       return Tpool->CanAllocate(n);
00151     }
00152 
00157     static FORCEINLINE bool CleaningPool()
00158     {
00159       return Tpool->cleaning;
00160     }
00161 
00167     static FORCEINLINE bool IsValidID(size_t index)
00168     {
00169       return Tpool->IsValidID(index);
00170     }
00171 
00178     static FORCEINLINE Titem *Get(size_t index)
00179     {
00180       return Tpool->Get(index);
00181     }
00182 
00189     static FORCEINLINE Titem *GetIfValid(size_t index)
00190     {
00191       return index < Tpool->first_unused ? Tpool->Get(index) : NULL;
00192     }
00193 
00199     static FORCEINLINE size_t GetPoolSize()
00200     {
00201       return Tpool->first_unused;
00202     }
00203 
00208     static FORCEINLINE size_t GetNumItems()
00209     {
00210       return Tpool->items;
00211     }
00212 
00220     static FORCEINLINE void PostDestructor(size_t index) { }
00221   };
00222 
00223 private:
00224   static const size_t NO_FREE_ITEM = MAX_UVALUE(size_t); 
00225 
00230   struct AllocCache {
00232     AllocCache *next;
00233   };
00234 
00236   AllocCache *alloc_cache;
00237 
00238   void *AllocateItem(size_t size, size_t index);
00239   void ResizeFor(size_t index);
00240   size_t FindFirstFree();
00241 
00242   void *GetNew(size_t size);
00243   void *GetNew(size_t size, size_t index);
00244 
00245   void FreeItem(size_t index);
00246 };
00247 
00248 #define FOR_ALL_ITEMS_FROM(type, iter, var, start) \
00249   for (size_t iter = start; var = NULL, iter < type::GetPoolSize(); iter++) \
00250     if ((var = type::Get(iter)) != NULL)
00251 
00252 #define FOR_ALL_ITEMS(type, iter, var) FOR_ALL_ITEMS_FROM(type, iter, var, 0)
00253 
00254 #endif /* POOL_TYPE_HPP */

Generated on Wed Apr 13 00:47:46 2011 for OpenTTD by  doxygen 1.6.1