yapf_costcache.hpp

Go to the documentation of this file.
00001 /* $Id: yapf_costcache.hpp 18826 2010-01-16 14:22:19Z frosch $ */
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  YAPF_COSTCACHE_HPP
00013 #define  YAPF_COSTCACHE_HPP
00014 
00015 #include "../../date_func.h"
00016 
00021 template <class Types>
00022 class CYapfSegmentCostCacheNoneT
00023 {
00024 public:
00025   typedef typename Types::Tpf Tpf;              
00026   typedef typename Types::NodeList::Titem Node; 
00027 
00030   FORCEINLINE bool PfNodeCacheFetch(Node& n)
00031   {
00032     return false;
00033   }
00034 
00037   FORCEINLINE void PfNodeCacheFlush(Node& n)
00038   {
00039   }
00040 };
00041 
00042 
00047 template <class Types>
00048 class CYapfSegmentCostCacheLocalT
00049 {
00050 public:
00051   typedef typename Types::Tpf Tpf;              
00052   typedef typename Types::NodeList::Titem Node; 
00053   typedef typename Node::Key Key;               
00054   typedef typename Node::CachedData CachedData;
00055   typedef typename CachedData::Key CacheKey;
00056   typedef SmallArray<CachedData> LocalCache;
00057 
00058 protected:
00059   LocalCache      m_local_cache;
00060 
00062   FORCEINLINE Tpf& Yapf()
00063   {
00064     return *static_cast<Tpf*>(this);
00065   }
00066 
00067 public:
00070   FORCEINLINE bool PfNodeCacheFetch(Node& n)
00071   {
00072     CacheKey key(n.GetKey());
00073     Yapf().ConnectNodeToCachedData(n, *new (m_local_cache.Append()) CachedData(key));
00074     return false;
00075   }
00076 
00079   FORCEINLINE void PfNodeCacheFlush(Node& n)
00080   {
00081   }
00082 };
00083 
00084 
00090 struct CSegmentCostCacheBase
00091 {
00092   static int   s_rail_change_counter;
00093 
00094   static void NotifyTrackLayoutChange(TileIndex tile, Track track)
00095   {
00096     s_rail_change_counter++;
00097   }
00098 };
00099 
00100 
00109 template <class Tsegment>
00110 struct CSegmentCostCacheT
00111   : public CSegmentCostCacheBase
00112 {
00113   enum {c_hash_bits = 14};
00114 
00115   typedef CHashTableT<Tsegment, c_hash_bits> HashTable;
00116   typedef SmallArray<Tsegment> Heap;
00117   typedef typename Tsegment::Key Key;    
00118 
00119   HashTable    m_map;
00120   Heap         m_heap;
00121 
00122   FORCEINLINE CSegmentCostCacheT() {}
00123 
00125   FORCEINLINE void Flush()
00126   {
00127     m_map.Clear();
00128     m_heap.Clear();
00129   }
00130 
00131   FORCEINLINE Tsegment& Get(Key& key, bool *found)
00132   {
00133     Tsegment *item = m_map.Find(key);
00134     if (item == NULL) {
00135       *found = false;
00136       item = new (m_heap.Append()) Tsegment(key);
00137       m_map.Push(*item);
00138     } else {
00139       *found = true;
00140     }
00141     return *item;
00142   }
00143 };
00144 
00149 template <class Types>
00150 class CYapfSegmentCostCacheGlobalT
00151   : public CYapfSegmentCostCacheLocalT<Types>
00152 {
00153 public:
00154   typedef CYapfSegmentCostCacheLocalT<Types> Tlocal;
00155   typedef typename Types::Tpf Tpf;              
00156   typedef typename Types::NodeList::Titem Node; 
00157   typedef typename Node::Key Key;    
00158   typedef typename Node::CachedData CachedData;
00159   typedef typename CachedData::Key CacheKey;
00160   typedef CSegmentCostCacheT<CachedData> Cache;
00161 
00162 protected:
00163   Cache&      m_global_cache;
00164 
00165   FORCEINLINE CYapfSegmentCostCacheGlobalT() : m_global_cache(stGetGlobalCache()) {};
00166 
00168   FORCEINLINE Tpf& Yapf()
00169   {
00170     return *static_cast<Tpf*>(this);
00171   }
00172 
00173   FORCEINLINE static Cache& stGetGlobalCache()
00174   {
00175     static int last_rail_change_counter = 0;
00176     static Date last_date = 0;
00177     static Cache C;
00178 
00179     /* some statistics */
00180     if (last_date != _date) {
00181       last_date = _date;
00182       DEBUG(yapf, 2, "Pf time today: %5d ms", _total_pf_time_us / 1000);
00183       _total_pf_time_us = 0;
00184     }
00185 
00186     /* delete the cache sometimes... */
00187     if (last_rail_change_counter != Cache::s_rail_change_counter) {
00188       last_rail_change_counter = Cache::s_rail_change_counter;
00189       C.Flush();
00190     }
00191     return C;
00192   }
00193 
00194 public:
00197   FORCEINLINE bool PfNodeCacheFetch(Node& n)
00198   {
00199     if (!Yapf().CanUseGlobalCache(n)) {
00200       return Tlocal::PfNodeCacheFetch(n);
00201     }
00202     CacheKey key(n.GetKey());
00203     bool found;
00204     CachedData& item = m_global_cache.Get(key, &found);
00205     Yapf().ConnectNodeToCachedData(n, item);
00206     return found;
00207   }
00208 
00211   FORCEINLINE void PfNodeCacheFlush(Node& n)
00212   {
00213   }
00214 };
00215 
00216 #endif /* YAPF_COSTCACHE_HPP */

Generated on Sat Nov 20 20:59:07 2010 for OpenTTD by  doxygen 1.6.1