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