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