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   FORCEINLINE bool PfNodeCacheFetch(Node& n)
00034   {
00035     return false;
00036   }
00037 
00042   FORCEINLINE 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   FORCEINLINE Tpf& Yapf()
00069   {
00070     return *static_cast<Tpf*>(this);
00071   }
00072 
00073 public:
00078   FORCEINLINE 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   FORCEINLINE 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   FORCEINLINE CSegmentCostCacheT() {}
00137 
00139   FORCEINLINE void Flush()
00140   {
00141     m_map.Clear();
00142     m_heap.Clear();
00143   }
00144 
00145   FORCEINLINE 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   FORCEINLINE CYapfSegmentCostCacheGlobalT() : m_global_cache(stGetGlobalCache()) {};
00181 
00183   FORCEINLINE Tpf& Yapf()
00184   {
00185     return *static_cast<Tpf*>(this);
00186   }
00187 
00188   FORCEINLINE 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   FORCEINLINE 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   FORCEINLINE void PfNodeCacheFlush(Node& n)
00231   {
00232   }
00233 };
00234 
00235 #endif /* YAPF_COSTCACHE_HPP */

Generated on Thu Apr 14 00:48:17 2011 for OpenTTD by  doxygen 1.6.1