# yapf_costcache.hpp

Go to the documentation of this file.

    00001 /* $Id: yapf_costcache.hpp 14949 2009-01-10 00:31:47Z 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 */