pool_type.hpp

Go to the documentation of this file.
00001 /* $Id: pool_type.hpp 21886 2011-01-22 09:53:15Z rubidium $ */
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 
00036   bool cleaning;       
00037 
00038   Titem **data;        
00039 
00040   Pool(const char *name);
00041   void CleanPool();
00042 
00049   FORCEINLINE Titem *Get(size_t index)
00050   {
00051     assert(index < this->first_unused);
00052     return this->data[index];
00053   }
00054 
00060   FORCEINLINE bool IsValidID(size_t index)
00061   {
00062     return index < this->first_unused && this->Get(index) != NULL;
00063   }
00064 
00070   FORCEINLINE bool CanAllocate(size_t n = 1)
00071   {
00072     return this->items <= Tmax_size - n;
00073   }
00074 
00079   template <struct Pool<Titem, Tindex, Tgrowth_step, Tmax_size, Tcache, Tzero> *Tpool>
00080   struct PoolItem {
00081     Tindex index; 
00082 
00089     FORCEINLINE void *operator new(size_t size)
00090     {
00091       return Tpool->GetNew(size);
00092     }
00093 
00099     FORCEINLINE void operator delete(void *p)
00100     {
00101       Titem *pn = (Titem *)p;
00102       assert(pn == Tpool->Get(pn->index));
00103       Tpool->FreeItem(pn->index);
00104     }
00105 
00114     FORCEINLINE void *operator new(size_t size, size_t index)
00115     {
00116       return Tpool->GetNew(size, index);
00117     }
00118 
00127     FORCEINLINE void *operator new(size_t size, void *ptr)
00128     {
00129       for (size_t i = 0; i < Tpool->first_unused; i++) {
00130         /* Don't allow creating new objects over existing.
00131          * Even if we called the destructor and reused this memory,
00132          * we don't know whether 'size' and size of currently allocated
00133          * memory are the same (because of possible inheritance).
00134          * Use { size_t index = item->index; delete item; new (index) item; }
00135          * instead to make sure destructor is called and no memory leaks. */
00136         assert(ptr != Tpool->data[i]);
00137       }
00138       return ptr;
00139     }
00140 
00141 
00149     static FORCEINLINE bool CanAllocateItem(size_t n = 1)
00150     {
00151       return Tpool->CanAllocate(n);
00152     }
00153 
00158     static FORCEINLINE bool CleaningPool()
00159     {
00160       return Tpool->cleaning;
00161     }
00162 
00168     static FORCEINLINE bool IsValidID(size_t index)
00169     {
00170       return Tpool->IsValidID(index);
00171     }
00172 
00179     static FORCEINLINE Titem *Get(size_t index)
00180     {
00181       return Tpool->Get(index);
00182     }
00183 
00190     static FORCEINLINE Titem *GetIfValid(size_t index)
00191     {
00192       return index < Tpool->first_unused ? Tpool->Get(index) : NULL;
00193     }
00194 
00200     static FORCEINLINE size_t GetPoolSize()
00201     {
00202       return Tpool->first_unused;
00203     }
00204 
00209     static FORCEINLINE size_t GetNumItems()
00210     {
00211       return Tpool->items;
00212     }
00213 
00221     static FORCEINLINE void PostDestructor(size_t index) { }
00222   };
00223 
00224 private:
00225   static const size_t NO_FREE_ITEM = MAX_UVALUE(size_t); 
00226 
00231   struct AllocCache {
00233     AllocCache *next;
00234   };
00235 
00237   AllocCache *alloc_cache;
00238 
00239   void *AllocateItem(size_t size, size_t index);
00240   void ResizeFor(size_t index);
00241   size_t FindFirstFree();
00242 
00243   void *GetNew(size_t size);
00244   void *GetNew(size_t size, size_t index);
00245 
00246   void FreeItem(size_t index);
00247 };
00248 
00249 #define FOR_ALL_ITEMS_FROM(type, iter, var, start) \
00250   for (size_t iter = start; var = NULL, iter < type::GetPoolSize(); iter++) \
00251     if ((var = type::Get(iter)) != NULL)
00252 
00253 #define FOR_ALL_ITEMS(type, iter, var) FOR_ALL_ITEMS_FROM(type, iter, var, 0)
00254 
00255 #endif /* POOL_TYPE_HPP */

Generated on Fri Feb 4 20:53:39 2011 for OpenTTD by  doxygen 1.6.1