# yapf_costcache.hpp

Go to the documentation of this file.

    00001 /* $Id$ */
    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
    00022 template <class Types>
    00023 class CYapfSegmentCostCacheNoneT
    00024 {
    00025 public:
    00026   typedef typename Types::Tpf Tpf;
    00027   typedef typename Types::NodeList::Titem Node;
    00028
    00033   inline bool PfNodeCacheFetch(Node& n)
    00034   {
    00035     return false;
    00036   }
    00037
    00042   inline void PfNodeCacheFlush(Node& n)
    00043   {
    00044   }
    00045 };
    00046
    00047
    00053 template <class Types>
    00054 class CYapfSegmentCostCacheLocalT
    00055 {
    00056 public:
    00057   typedef typename Types::Tpf Tpf;
    00058   typedef typename Types::NodeList::Titem Node;
    00059   typedef typename Node::Key Key;
    00060   typedef typename Node::CachedData CachedData;
    00061   typedef typename CachedData::Key CacheKey;
    00062   typedef SmallArray<CachedData> LocalCache;
    00063
    00064 protected:
    00065   LocalCache      m_local_cache;
    00066
    00068   inline Tpf& Yapf()
    00069   {
    00070     return *static_cast<Tpf*>(this);
    00071   }
    00072
    00073 public:
    00078   inline bool PfNodeCacheFetch(Node& n)
    00079   {
    00080     CacheKey key(n.GetKey());
    00081     Yapf().ConnectNodeToCachedData(n, *new (m_local_cache.Append()) CachedData(key));
    00082     return false;
    00083   }
    00084
    00089   inline void PfNodeCacheFlush(Node& n)
    00090   {
    00091   }
    00092 };
    00093
    00094
    00102 struct CSegmentCostCacheBase
    00103 {
    00104   static int   s_rail_change_counter;
    00105
    00106   static void NotifyTrackLayoutChange(TileIndex tile, Track track)
    00107   {
    00108     s_rail_change_counter++;
    00109   }
    00110 };
    00111
    00112
    00123 template <class Tsegment>
    00124 struct CSegmentCostCacheT
    00125   : public CSegmentCostCacheBase
    00126 {
    00127   static const int C_HASH_BITS = 14;
    00128
    00129   typedef CHashTableT<Tsegment, C_HASH_BITS> HashTable;
    00130   typedef SmallArray<Tsegment> Heap;
    00131   typedef typename Tsegment::Key Key;
    00132
    00133   HashTable    m_map;
    00134   Heap         m_heap;
    00135
    00136   inline CSegmentCostCacheT() {}
    00137
    00139   inline void Flush()
    00140   {
    00141     m_map.Clear();
    00142     m_heap.Clear();
    00143   }
    00144
    00145   inline Tsegment& Get(Key& key, bool *found)
    00146   {
    00147     Tsegment *item = m_map.Find(key);
    00148     if (item == NULL) {
    00149       *found = false;
    00150       item = new (m_heap.Append()) Tsegment(key);
    00151       m_map.Push(*item);
    00152     } else {
    00153       *found = true;
    00154     }
    00155     return *item;
    00156   }
    00157 };
    00158
    00164 template <class Types>
    00165 class CYapfSegmentCostCacheGlobalT
    00166   : public CYapfSegmentCostCacheLocalT<Types>
    00167 {
    00168 public:
    00169   typedef CYapfSegmentCostCacheLocalT<Types> Tlocal;
    00170   typedef typename Types::Tpf Tpf;
    00171   typedef typename Types::NodeList::Titem Node;
    00172   typedef typename Node::Key Key;
    00173   typedef typename Node::CachedData CachedData;
    00174   typedef typename CachedData::Key CacheKey;
    00175   typedef CSegmentCostCacheT<CachedData> Cache;
    00176
    00177 protected:
    00178   Cache&      m_global_cache;
    00179
    00180   inline CYapfSegmentCostCacheGlobalT() : m_global_cache(stGetGlobalCache()) {};
    00181
    00183   inline Tpf& Yapf()
    00184   {
    00185     return *static_cast<Tpf*>(this);
    00186   }
    00187
    00188   inline static Cache& stGetGlobalCache()
    00189   {
    00190     static int last_rail_change_counter = 0;
    00191     static Date last_date = 0;
    00192     static Cache C;
    00193
    00194     /* some statistics */
    00195     if (last_date != _date) {
    00196       last_date = _date;
    00197       DEBUG(yapf, 2, "Pf time today: %5d ms", _total_pf_time_us / 1000);
    00198       _total_pf_time_us = 0;
    00199     }
    00200
    00201     /* delete the cache sometimes... */
    00202     if (last_rail_change_counter != Cache::s_rail_change_counter) {
    00203       last_rail_change_counter = Cache::s_rail_change_counter;
    00204       C.Flush();
    00205     }
    00206     return C;
    00207   }
    00208
    00209 public:
    00214   inline bool PfNodeCacheFetch(Node& n)
    00215   {
    00216     if (!Yapf().CanUseGlobalCache(n)) {
    00217       return Tlocal::PfNodeCacheFetch(n);
    00218     }
    00219     CacheKey key(n.GetKey());
    00220     bool found;
    00221     CachedData& item = m_global_cache.Get(key, &found);
    00222     Yapf().ConnectNodeToCachedData(n, item);
    00223     return found;
    00224   }
    00225
    00230   inline void PfNodeCacheFlush(Node& n)
    00231   {
    00232   }
    00233 };
    00234
    00235 #endif /* YAPF_COSTCACHE_HPP */