yapf_costcache.hpp

Go to the documentation of this file.
00001 /* $Id: yapf_costcache.hpp 15718 2009-03-15 00:32:18Z 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()
00056   {
00057     return *static_cast<Tpf*>(this);
00058   }
00059 
00060 public:
00063   FORCEINLINE bool PfNodeCacheFetch(Node& n)
00064   {
00065     CacheKey key(n.GetKey());
00066     Yapf().ConnectNodeToCachedData(n, *new (&m_local_cache.AddNC()) CachedData(key));
00067     return false;
00068   }
00069 
00072   FORCEINLINE void PfNodeCacheFlush(Node& n)
00073   {
00074   }
00075 };
00076 
00077 
00083 struct CSegmentCostCacheBase
00084 {
00085   static int   s_rail_change_counter;
00086 
00087   static void NotifyTrackLayoutChange(TileIndex tile, Track track)
00088   {
00089     s_rail_change_counter++;
00090   }
00091 };
00092 
00093 
00102 template <class Tsegment>
00103 struct CSegmentCostCacheT
00104   : public CSegmentCostCacheBase
00105 {
00106   enum {c_hash_bits = 14};
00107 
00108   typedef CHashTableT<Tsegment, c_hash_bits> HashTable;
00109   typedef CArrayT<Tsegment> Heap;
00110   typedef typename Tsegment::Key Key;    
00111 
00112   HashTable    m_map;
00113   Heap         m_heap;
00114 
00115   FORCEINLINE CSegmentCostCacheT() {}
00116 
00118   FORCEINLINE void Flush()
00119   {
00120     m_map.Clear();
00121     m_heap.Clear();
00122   }
00123 
00124   FORCEINLINE Tsegment& Get(Key& key, bool *found)
00125   {
00126     Tsegment *item = m_map.Find(key);
00127     if (item == NULL) {
00128       *found = false;
00129       item = new (&m_heap.AddNC()) Tsegment(key);
00130       m_map.Push(*item);
00131     } else {
00132       *found = true;
00133     }
00134     return *item;
00135   }
00136 };
00137 
00142 template <class Types>
00143 class CYapfSegmentCostCacheGlobalT
00144   : public CYapfSegmentCostCacheLocalT<Types>
00145 {
00146 public:
00147   typedef CYapfSegmentCostCacheLocalT<Types> Tlocal;
00148   typedef typename Types::Tpf Tpf;              
00149   typedef typename Types::NodeList::Titem Node; 
00150   typedef typename Node::Key Key;    
00151   typedef typename Node::CachedData CachedData;
00152   typedef typename CachedData::Key CacheKey;
00153   typedef CSegmentCostCacheT<CachedData> Cache;
00154 
00155 protected:
00156   Cache&      m_global_cache;
00157 
00158   FORCEINLINE CYapfSegmentCostCacheGlobalT() : m_global_cache(stGetGlobalCache()) {};
00159 
00161   FORCEINLINE Tpf& Yapf()
00162   {
00163     return *static_cast<Tpf*>(this);
00164   }
00165 
00166   FORCEINLINE static Cache& stGetGlobalCache()
00167   {
00168     static int last_rail_change_counter = 0;
00169     static Date last_date = 0;
00170     static Cache C;
00171 
00172     /* some statistics */
00173     if (last_date != _date) {
00174       last_date = _date;
00175       DEBUG(yapf, 2, "Pf time today: %5d ms", _total_pf_time_us / 1000);
00176       _total_pf_time_us = 0;
00177     }
00178 
00179     /* delete the cache sometimes... */
00180     if (last_rail_change_counter != Cache::s_rail_change_counter) {
00181       last_rail_change_counter = Cache::s_rail_change_counter;
00182       C.Flush();
00183     }
00184     return C;
00185   }
00186 
00187 public:
00190   FORCEINLINE bool PfNodeCacheFetch(Node& n)
00191   {
00192     if (!Yapf().CanUseGlobalCache(n)) {
00193       return Tlocal::PfNodeCacheFetch(n);
00194     }
00195     CacheKey key(n.GetKey());
00196     bool found;
00197     CachedData& item = m_global_cache.Get(key, &found);
00198     Yapf().ConnectNodeToCachedData(n, item);
00199     return found;
00200   }
00201 
00204   FORCEINLINE void PfNodeCacheFlush(Node& n)
00205   {
00206   }
00207 };
00208 
00209 #endif /* YAPF_COSTCACHE_HPP */

Generated on Wed Jun 3 19:05:17 2009 for OpenTTD by  doxygen 1.5.6