yapf_costcache.hpp

Go to the documentation of this file.
00001 /* $Id: yapf_costcache.hpp 11702 2007-12-26 13:50:40Z rubidium $ */
00002 
00005 #ifndef  YAPF_COSTCACHE_HPP
00006 #define  YAPF_COSTCACHE_HPP
00007 
00008 #include "../date_func.h"
00009 
00014 template <class Types>
00015 class CYapfSegmentCostCacheNoneT
00016 {
00017 public:
00018   typedef typename Types::Tpf Tpf;              
00019   typedef typename Types::NodeList::Titem Node; 
00020 
00023   FORCEINLINE bool PfNodeCacheFetch(Node& n)
00024   {
00025     return false;
00026   };
00027 
00030   FORCEINLINE void PfNodeCacheFlush(Node& n)
00031   {
00032   };
00033 };
00034 
00035 
00040 template <class Types>
00041 class CYapfSegmentCostCacheLocalT
00042 {
00043 public:
00044   typedef typename Types::Tpf Tpf;              
00045   typedef typename Types::NodeList::Titem Node; 
00046   typedef typename Node::Key Key;               
00047   typedef typename Node::CachedData CachedData;
00048   typedef typename CachedData::Key CacheKey;
00049   typedef CArrayT<CachedData> LocalCache;
00050 
00051 protected:
00052   LocalCache      m_local_cache;
00053 
00055   FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
00056 
00057 public:
00060   FORCEINLINE bool PfNodeCacheFetch(Node& n)
00061   {
00062     CacheKey key(n.GetKey());
00063     Yapf().ConnectNodeToCachedData(n, *new (&m_local_cache.AddNC()) CachedData(key));
00064     return false;
00065   };
00066 
00069   FORCEINLINE void PfNodeCacheFlush(Node& n)
00070   {
00071   };
00072 };
00073 
00074 
00080 struct CSegmentCostCacheBase
00081 {
00082   static int   s_rail_change_counter;
00083 
00084   static void NotifyTrackLayoutChange(TileIndex tile, Track track) {s_rail_change_counter++;}
00085 };
00086 
00087 
00096 template <class Tsegment>
00097 struct CSegmentCostCacheT
00098   : public CSegmentCostCacheBase
00099 {
00100   enum {c_hash_bits = 14};
00101 
00102   typedef CHashTableT<Tsegment, c_hash_bits> HashTable;
00103   typedef CArrayT<Tsegment> Heap;
00104   typedef typename Tsegment::Key Key;    
00105 
00106   HashTable    m_map;
00107   Heap         m_heap;
00108 
00109   FORCEINLINE CSegmentCostCacheT() {}
00110 
00112   FORCEINLINE void Flush() {m_map.Clear(); m_heap.Clear();};
00113 
00114   FORCEINLINE Tsegment& Get(Key& key, bool *found)
00115   {
00116     Tsegment* item = m_map.Find(key);
00117     if (item == NULL) {
00118       *found = false;
00119       item = new (&m_heap.AddNC()) Tsegment(key);
00120       m_map.Push(*item);
00121     } else {
00122       *found = true;
00123     }
00124     return *item;
00125   }
00126 };
00127 
00132 template <class Types>
00133 class CYapfSegmentCostCacheGlobalT
00134   : public CYapfSegmentCostCacheLocalT<Types>
00135 {
00136 public:
00137   typedef CYapfSegmentCostCacheLocalT<Types> Tlocal;
00138   typedef typename Types::Tpf Tpf;              
00139   typedef typename Types::NodeList::Titem Node; 
00140   typedef typename Node::Key Key;    
00141   typedef typename Node::CachedData CachedData;
00142   typedef typename CachedData::Key CacheKey;
00143   typedef CSegmentCostCacheT<CachedData> Cache;
00144 
00145 protected:
00146   Cache&      m_global_cache;
00147 
00148   FORCEINLINE CYapfSegmentCostCacheGlobalT() : m_global_cache(stGetGlobalCache()) {};
00149 
00151   FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
00152 
00153   FORCEINLINE static Cache& stGetGlobalCache()
00154   {
00155     static int last_rail_change_counter = 0;
00156     static Date last_date = 0;
00157     static Cache C;
00158 
00159     // some statistics
00160     if (last_date != _date) {
00161       last_date = _date;
00162       DEBUG(yapf, 2, "Pf time today: %5d ms", _total_pf_time_us / 1000);
00163       _total_pf_time_us = 0;
00164     }
00165 
00166     // delete the cache sometimes...
00167     if (last_rail_change_counter != Cache::s_rail_change_counter) {
00168       last_rail_change_counter = Cache::s_rail_change_counter;
00169       C.Flush();
00170     }
00171     return C;
00172   }
00173 
00174 public:
00177   FORCEINLINE bool PfNodeCacheFetch(Node& n)
00178   {
00179     if (!Yapf().CanUseGlobalCache(n)) {
00180       return Tlocal::PfNodeCacheFetch(n);
00181     }
00182     CacheKey key(n.GetKey());
00183     bool found;
00184     CachedData& item = m_global_cache.Get(key, &found);
00185     Yapf().ConnectNodeToCachedData(n, item);
00186     return found;
00187   };
00188 
00191   FORCEINLINE void PfNodeCacheFlush(Node& n)
00192   {
00193   };
00194 
00195 };
00196 
00197 
00198 
00199 
00200 #endif /* YAPF_COSTCACHE_HPP */

Generated on Wed Oct 1 17:03:26 2008 for openttd by  doxygen 1.5.6