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 */