(svn r27953) -Cleanup: Adjust other languages for r27952
[openttd.git] / src / pathfinder / yapf / yapf_costcache.hpp
blobf16d4054c6a4f7958533b9babeefcfce40959a12
1 /* $Id$ */
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
10 /** @file yapf_costcache.hpp Caching of segment costs. */
12 #ifndef YAPF_COSTCACHE_HPP
13 #define YAPF_COSTCACHE_HPP
15 #include "../../date_func.h"
17 /**
18 * CYapfSegmentCostCacheNoneT - the formal only yapf cost cache provider that implements
19 * PfNodeCacheFetch() and PfNodeCacheFlush() callbacks. Used when nodes don't have CachedData
20 * defined (they don't count with any segment cost caching).
22 template <class Types>
23 class CYapfSegmentCostCacheNoneT
25 public:
26 typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
27 typedef typename Types::NodeList::Titem Node; ///< this will be our node type
29 /**
30 * Called by YAPF to attach cached or local segment cost data to the given node.
31 * @return true if globally cached data were used or false if local data was used
33 inline bool PfNodeCacheFetch(Node &n)
35 return false;
38 /**
39 * Called by YAPF to flush the cached segment cost data back into cache storage.
40 * Current cache implementation doesn't use that.
42 inline void PfNodeCacheFlush(Node &n)
48 /**
49 * CYapfSegmentCostCacheLocalT - the yapf cost cache provider that implements fake segment
50 * cost caching functionality for yapf. Used when node needs caching, but you don't want to
51 * cache the segment costs.
53 template <class Types>
54 class CYapfSegmentCostCacheLocalT
56 public:
57 typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
58 typedef typename Types::NodeList::Titem Node; ///< this will be our node type
59 typedef typename Node::Key Key; ///< key to hash tables
60 typedef typename Node::CachedData CachedData;
61 typedef typename CachedData::Key CacheKey;
62 typedef SmallArray<CachedData> LocalCache;
64 protected:
65 LocalCache m_local_cache;
67 /** to access inherited path finder */
68 inline Tpf& Yapf()
70 return *static_cast<Tpf *>(this);
73 public:
74 /**
75 * Called by YAPF to attach cached or local segment cost data to the given node.
76 * @return true if globally cached data were used or false if local data was used
78 inline bool PfNodeCacheFetch(Node &n)
80 CacheKey key(n.GetKey());
81 Yapf().ConnectNodeToCachedData(n, *new (m_local_cache.Append()) CachedData(key));
82 return false;
85 /**
86 * Called by YAPF to flush the cached segment cost data back into cache storage.
87 * Current cache implementation doesn't use that.
89 inline void PfNodeCacheFlush(Node &n)
95 /**
96 * Base class for segment cost cache providers. Contains global counter
97 * of track layout changes and static notification function called whenever
98 * the track layout changes. It is implemented as base class because it needs
99 * to be shared between all rail YAPF types (one shared counter, one notification
100 * function.
102 struct CSegmentCostCacheBase
104 static int s_rail_change_counter;
106 static void NotifyTrackLayoutChange(TileIndex tile, Track track)
108 s_rail_change_counter++;
114 * CSegmentCostCacheT - template class providing hash-map and storage (heap)
115 * of Tsegment structures. Each rail node contains pointer to the segment
116 * that contains cached (or non-cached) segment cost information. Nodes can
117 * differ by key type, but they use the same segment type. Segment key should
118 * be always the same (TileIndex + DiagDirection) that represent the beginning
119 * of the segment (origin tile and exit-dir from this tile).
120 * Different CYapfCachedCostT types can share the same type of CSegmentCostCacheT.
121 * Look at CYapfRailSegment (yapf_node_rail.hpp) for the segment example
123 template <class Tsegment>
124 struct CSegmentCostCacheT : public CSegmentCostCacheBase {
125 static const int C_HASH_BITS = 14;
127 typedef CHashTableT<Tsegment, C_HASH_BITS> HashTable;
128 typedef SmallArray<Tsegment> Heap;
129 typedef typename Tsegment::Key Key; ///< key to hash table
131 HashTable m_map;
132 Heap m_heap;
134 inline CSegmentCostCacheT() {}
136 /** flush (clear) the cache */
137 inline void Flush()
139 m_map.Clear();
140 m_heap.Clear();
143 inline Tsegment& Get(Key &key, bool *found)
145 Tsegment *item = m_map.Find(key);
146 if (item == NULL) {
147 *found = false;
148 item = new (m_heap.Append()) Tsegment(key);
149 m_map.Push(*item);
150 } else {
151 *found = true;
153 return *item;
158 * CYapfSegmentCostCacheGlobalT - the yapf cost cache provider that adds the segment cost
159 * caching functionality to yapf. Using this class as base of your will provide the global
160 * segment cost caching services for your Nodes.
162 template <class Types>
163 class CYapfSegmentCostCacheGlobalT : public CYapfSegmentCostCacheLocalT<Types> {
164 public:
165 typedef CYapfSegmentCostCacheLocalT<Types> Tlocal;
166 typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
167 typedef typename Types::NodeList::Titem Node; ///< this will be our node type
168 typedef typename Node::Key Key; ///< key to hash tables
169 typedef typename Node::CachedData CachedData;
170 typedef typename CachedData::Key CacheKey;
171 typedef CSegmentCostCacheT<CachedData> Cache;
173 protected:
174 Cache &m_global_cache;
176 inline CYapfSegmentCostCacheGlobalT() : m_global_cache(stGetGlobalCache()) {};
178 /** to access inherited path finder */
179 inline Tpf& Yapf()
181 return *static_cast<Tpf *>(this);
184 inline static Cache& stGetGlobalCache()
186 static int last_rail_change_counter = 0;
187 static Date last_date = 0;
188 static Cache C;
190 /* some statistics */
191 if (last_date != _date) {
192 last_date = _date;
193 DEBUG(yapf, 2, "Pf time today: %5d ms", _total_pf_time_us / 1000);
194 _total_pf_time_us = 0;
197 /* delete the cache sometimes... */
198 if (last_rail_change_counter != Cache::s_rail_change_counter) {
199 last_rail_change_counter = Cache::s_rail_change_counter;
200 C.Flush();
202 return C;
205 public:
207 * Called by YAPF to attach cached or local segment cost data to the given node.
208 * @return true if globally cached data were used or false if local data was used
210 inline bool PfNodeCacheFetch(Node &n)
212 if (!Yapf().CanUseGlobalCache(n)) {
213 return Tlocal::PfNodeCacheFetch(n);
215 CacheKey key(n.GetKey());
216 bool found;
217 CachedData &item = m_global_cache.Get(key, &found);
218 Yapf().ConnectNodeToCachedData(n, item);
219 return found;
223 * Called by YAPF to flush the cached segment cost data back into cache storage.
224 * Current cache implementation doesn't use that.
226 inline void PfNodeCacheFlush(Node &n)
231 #endif /* YAPF_COSTCACHE_HPP */