(svn r28004) -Update from Eints:
[openttd.git] / src / linkgraph / linkgraph.h
blob799f22c78007dd80bb83e7e8afda9398f93bffe3
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 linkgraph.h Declaration of link graph classes used for cargo distribution. */
12 #ifndef LINKGRAPH_H
13 #define LINKGRAPH_H
15 #include "../core/pool_type.hpp"
16 #include "../core/smallmap_type.hpp"
17 #include "../core/smallmatrix_type.hpp"
18 #include "../station_base.h"
19 #include "../cargotype.h"
20 #include "../date_func.h"
21 #include "linkgraph_type.h"
23 struct SaveLoad;
24 class LinkGraph;
26 /**
27 * Type of the pool for link graph components. Each station can be in at up to
28 * 32 link graphs. So we allow for plenty of them to be created.
30 typedef Pool<LinkGraph, LinkGraphID, 32, 0xFFFF> LinkGraphPool;
31 /** The actual pool with link graphs. */
32 extern LinkGraphPool _link_graph_pool;
34 /**
35 * A connected component of a link graph. Contains a complete set of stations
36 * connected by links as nodes and edges. Each component also holds a copy of
37 * the link graph settings at the time of its creation. The global settings
38 * might change between the creation and join time so we can't rely on them.
40 class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> {
41 public:
43 /**
44 * Node of the link graph. contains all relevant information from the associated
45 * station. It's copied so that the link graph job can work on its own data set
46 * in a separate thread.
48 struct BaseNode {
49 uint supply; ///< Supply at the station.
50 uint demand; ///< Acceptance at the station.
51 StationID station; ///< Station ID.
52 TileIndex xy; ///< Location of the station referred to by the node.
53 Date last_update; ///< When the supply was last updated.
54 void Init(TileIndex xy = INVALID_TILE, StationID st = INVALID_STATION, uint demand = 0);
57 /**
58 * An edge in the link graph. Corresponds to a link between two stations or at
59 * least the distance between them. Edges from one node to itself contain the
60 * ID of the opposite Node of the first active edge (i.e. not just distance) in
61 * the column as next_edge.
63 struct BaseEdge {
64 uint capacity; ///< Capacity of the link.
65 uint usage; ///< Usage of the link.
66 Date last_unrestricted_update; ///< When the unrestricted part of the link was last updated.
67 Date last_restricted_update; ///< When the restricted part of the link was last updated.
68 NodeID next_edge; ///< Destination of next valid edge starting at the same source node.
69 void Init();
72 /**
73 * Wrapper for an edge (const or not) allowing retrieval, but no modification.
74 * @tparam Tedge Actual edge class, may be "const BaseEdge" or just "BaseEdge".
76 template<typename Tedge>
77 class EdgeWrapper {
78 protected:
79 Tedge &edge; ///< Actual edge to be used.
81 public:
83 /**
84 * Wrap a an edge.
85 * @param edge Edge to be wrapped.
87 EdgeWrapper (Tedge &edge) : edge(edge) {}
89 /**
90 * Get edge's capacity.
91 * @return Capacity.
93 uint Capacity() const { return this->edge.capacity; }
95 /**
96 * Get edge's usage.
97 * @return Usage.
99 uint Usage() const { return this->edge.usage; }
102 * Get the date of the last update to the edge's unrestricted capacity.
103 * @return Last update.
105 Date LastUnrestrictedUpdate() const { return this->edge.last_unrestricted_update; }
108 * Get the date of the last update to the edge's restricted capacity.
109 * @return Last update.
111 Date LastRestrictedUpdate() const { return this->edge.last_restricted_update; }
114 * Get the date of the last update to any part of the edge's capacity.
115 * @return Last update.
117 Date LastUpdate() const { return max(this->edge.last_unrestricted_update, this->edge.last_restricted_update); }
121 * Wrapper for a node (const or not) allowing retrieval, but no modification.
122 * @tparam Tedge Actual node class, may be "const BaseNode" or just "BaseNode".
123 * @tparam Tedge Actual edge class, may be "const BaseEdge" or just "BaseEdge".
125 template<typename Tnode, typename Tedge>
126 class NodeWrapper {
127 protected:
128 Tnode &node; ///< Node being wrapped.
129 Tedge *edges; ///< Outgoing edges for wrapped node.
130 NodeID index; ///< ID of wrapped node.
132 public:
135 * Wrap a node.
136 * @param node Node to be wrapped.
137 * @param edges Outgoing edges for node to be wrapped.
138 * @param index ID of node to be wrapped.
140 NodeWrapper(Tnode &node, Tedge *edges, NodeID index) : node(node),
141 edges(edges), index(index) {}
144 * Get supply of wrapped node.
145 * @return Supply.
147 uint Supply() const { return this->node.supply; }
150 * Get demand of wrapped node.
151 * @return Demand.
153 uint Demand() const { return this->node.demand; }
156 * Get ID of station belonging to wrapped node.
157 * @return ID of node's station.
159 StationID Station() const { return this->node.station; }
162 * Get node's last update.
163 * @return Last update.
165 Date LastUpdate() const { return this->node.last_update; }
168 * Get the location of the station associated with the node.
169 * @return Location of the station.
171 TileIndex XY() const { return this->node.xy; }
175 * Base class for iterating across outgoing edges of a node. Only the real
176 * edges (those with capacity) are iterated. The ones with only distance
177 * information are skipped.
178 * @tparam Tedge Actual edge class. May be "BaseEdge" or "const BaseEdge".
179 * @tparam Titer Actual iterator class.
181 template <class Tedge, class Tedge_wrapper, class Titer>
182 class BaseEdgeIterator {
183 protected:
184 Tedge *base; ///< Array of edges being iterated.
185 NodeID current; ///< Current offset in edges array.
188 * A "fake" pointer to enable operator-> on temporaries. As the objects
189 * returned from operator* aren't references but real objects, we have
190 * to return something that implements operator->, but isn't a pointer
191 * from operator->. A fake pointer.
193 class FakePointer : public SmallPair<NodeID, Tedge_wrapper> {
194 public:
197 * Construct a fake pointer from a pair of NodeID and edge.
198 * @param pair Pair to be "pointed" to (in fact shallow-copied).
200 FakePointer(const SmallPair<NodeID, Tedge_wrapper> &pair) : SmallPair<NodeID, Tedge_wrapper>(pair) {}
203 * Retrieve the pair by operator->.
204 * @return Pair being "pointed" to.
206 SmallPair<NodeID, Tedge_wrapper> *operator->() { return this; }
209 public:
211 * Constructor.
212 * @param base Array of edges to be iterated.
213 * @param current ID of current node (to locate the first edge).
215 BaseEdgeIterator (Tedge *base, NodeID current) :
216 base(base),
217 current(current == INVALID_NODE ? current : base[current].next_edge)
221 * Prefix-increment.
222 * @return This.
224 Titer &operator++()
226 this->current = this->base[this->current].next_edge;
227 return static_cast<Titer &>(*this);
231 * Postfix-increment.
232 * @return Version of this before increment.
234 Titer operator++(int)
236 Titer ret(static_cast<Titer &>(*this));
237 this->current = this->base[this->current].next_edge;
238 return ret;
242 * Compare with some other edge iterator. The other one may be of a
243 * child class.
244 * @tparam Tother Class of other iterator.
245 * @param other Instance of other iterator.
246 * @return If the iterators have the same edge array and current node.
248 template<class Tother>
249 bool operator==(const Tother &other)
251 return this->base == other.base && this->current == other.current;
255 * Compare for inequality with some other edge iterator. The other one
256 * may be of a child class.
257 * @tparam Tother Class of other iterator.
258 * @param other Instance of other iterator.
259 * @return If either the edge arrays or the current nodes differ.
261 template<class Tother>
262 bool operator!=(const Tother &other)
264 return this->base != other.base || this->current != other.current;
268 * Dereference with operator*.
269 * @return Pair of current target NodeID and edge object.
271 SmallPair<NodeID, Tedge_wrapper> operator*() const
273 return SmallPair<NodeID, Tedge_wrapper>(this->current, Tedge_wrapper(this->base[this->current]));
277 * Dereference with operator->.
278 * @return Fake pointer to Pair of current target NodeID and edge object.
280 FakePointer operator->() const {
281 return FakePointer(this->operator*());
286 * A constant edge class.
288 typedef EdgeWrapper<const BaseEdge> ConstEdge;
291 * An updatable edge class.
293 class Edge : public EdgeWrapper<BaseEdge> {
294 public:
296 * Constructor
297 * @param edge Edge to be wrapped.
299 Edge(BaseEdge &edge) : EdgeWrapper<BaseEdge>(edge) {}
300 void Update(uint capacity, uint usage, EdgeUpdateMode mode);
301 void Restrict() { this->edge.last_unrestricted_update = INVALID_DATE; }
302 void Release() { this->edge.last_restricted_update = INVALID_DATE; }
306 * An iterator for const edges. Cannot be typedef'ed because of
307 * template-reference to ConstEdgeIterator itself.
309 class ConstEdgeIterator : public BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator> {
310 public:
312 * Constructor.
313 * @param edges Array of edges to be iterated over.
314 * @param current ID of current edge's end node.
316 ConstEdgeIterator(const BaseEdge *edges, NodeID current) :
317 BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator>(edges, current) {}
321 * An iterator for non-const edges. Cannot be typedef'ed because of
322 * template-reference to EdgeIterator itself.
324 class EdgeIterator : public BaseEdgeIterator<BaseEdge, Edge, EdgeIterator> {
325 public:
327 * Constructor.
328 * @param edges Array of edges to be iterated over.
329 * @param current ID of current edge's end node.
331 EdgeIterator(BaseEdge *edges, NodeID current) :
332 BaseEdgeIterator<BaseEdge, Edge, EdgeIterator>(edges, current) {}
336 * Constant node class. Only retrieval operations are allowed on both the
337 * node itself and its edges.
339 class ConstNode : public NodeWrapper<const BaseNode, const BaseEdge> {
340 public:
342 * Constructor.
343 * @param lg LinkGraph to get the node from.
344 * @param node ID of the node.
346 ConstNode(const LinkGraph *lg, NodeID node) :
347 NodeWrapper<const BaseNode, const BaseEdge>(lg->nodes[node], lg->edges[node], node)
351 * Get a ConstEdge. This is not a reference as the wrapper objects are
352 * not actually persistent.
353 * @param to ID of end node of edge.
354 * @return Constant edge wrapper.
356 ConstEdge operator[](NodeID to) const { return ConstEdge(this->edges[to]); }
359 * Get an iterator pointing to the start of the edges array.
360 * @return Constant edge iterator.
362 ConstEdgeIterator Begin() const { return ConstEdgeIterator(this->edges, this->index); }
365 * Get an iterator pointing beyond the end of the edges array.
366 * @return Constant edge iterator.
368 ConstEdgeIterator End() const { return ConstEdgeIterator(this->edges, INVALID_NODE); }
372 * Updatable node class. The node itself as well as its edges can be modified.
374 class Node : public NodeWrapper<BaseNode, BaseEdge> {
375 public:
377 * Constructor.
378 * @param lg LinkGraph to get the node from.
379 * @param node ID of the node.
381 Node(LinkGraph *lg, NodeID node) :
382 NodeWrapper<BaseNode, BaseEdge>(lg->nodes[node], lg->edges[node], node)
386 * Get an Edge. This is not a reference as the wrapper objects are not
387 * actually persistent.
388 * @param to ID of end node of edge.
389 * @return Edge wrapper.
391 Edge operator[](NodeID to) { return Edge(this->edges[to]); }
394 * Get an iterator pointing to the start of the edges array.
395 * @return Edge iterator.
397 EdgeIterator Begin() { return EdgeIterator(this->edges, this->index); }
400 * Get an iterator pointing beyond the end of the edges array.
401 * @return Constant edge iterator.
403 EdgeIterator End() { return EdgeIterator(this->edges, INVALID_NODE); }
406 * Update the node's supply and set last_update to the current date.
407 * @param supply Supply to be added.
409 void UpdateSupply(uint supply)
411 this->node.supply += supply;
412 this->node.last_update = _date;
416 * Update the node's location on the map.
417 * @param xy New location.
419 void UpdateLocation(TileIndex xy)
421 this->node.xy = xy;
425 * Set the node's demand.
426 * @param demand New demand for the node.
428 void SetDemand(uint demand)
430 this->node.demand = demand;
433 void AddEdge(NodeID to, uint capacity, uint usage, EdgeUpdateMode mode);
434 void UpdateEdge(NodeID to, uint capacity, uint usage, EdgeUpdateMode mode);
435 void RemoveEdge(NodeID to);
438 typedef SmallVector<BaseNode, 16> NodeVector;
439 typedef SmallMatrix<BaseEdge> EdgeMatrix;
441 /** Minimum effective distance for timeout calculation. */
442 static const uint MIN_TIMEOUT_DISTANCE = 32;
444 /** Minimum number of days between subsequent compressions of a LG. */
445 static const uint COMPRESSION_INTERVAL = 256;
448 * Scale a value from a link graph of age orig_age for usage in one of age
449 * target_age. Make sure that the value stays > 0 if it was > 0 before.
450 * @param val Value to be scaled.
451 * @param target_age Age of the target link graph.
452 * @param orig_age Age of the original link graph.
453 * @return scaled value.
455 inline static uint Scale(uint val, uint target_age, uint orig_age)
457 return val > 0 ? max(1U, val * target_age / orig_age) : 0;
460 /** Bare constructor, only for save/load. */
461 LinkGraph() : cargo(INVALID_CARGO), last_compression(0) {}
463 * Real constructor.
464 * @param cargo Cargo the link graph is about.
466 LinkGraph(CargoID cargo) : cargo(cargo), last_compression(_date) {}
468 void Init(uint size);
469 void ShiftDates(int interval);
470 void Compress();
471 void Merge(LinkGraph *other);
473 /* Splitting link graphs is intentionally not implemented.
474 * The overhead in determining connectedness would probably outweigh the
475 * benefit of having to deal with smaller graphs. In real world examples
476 * networks generally grow. Only rarely a network is permanently split.
477 * Reacting to temporary splits here would obviously create performance
478 * problems and detecting the temporary or permanent nature of splits isn't
479 * trivial. */
482 * Get a node with the specified id.
483 * @param num ID of the node.
484 * @return the Requested node.
486 inline Node operator[](NodeID num) { return Node(this, num); }
489 * Get a const reference to a node with the specified id.
490 * @param num ID of the node.
491 * @return the Requested node.
493 inline ConstNode operator[](NodeID num) const { return ConstNode(this, num); }
496 * Get the current size of the component.
497 * @return Size.
499 inline uint Size() const { return this->nodes.Length(); }
502 * Get date of last compression.
503 * @return Date of last compression.
505 inline Date LastCompression() const { return this->last_compression; }
508 * Get the cargo ID this component's link graph refers to.
509 * @return Cargo ID.
511 inline CargoID Cargo() const { return this->cargo; }
514 * Scale a value to its monthly equivalent, based on last compression.
515 * @param base Value to be scaled.
516 * @return Scaled value.
518 inline uint Monthly(uint base) const
520 return base * 30 / (_date - this->last_compression + 1);
523 NodeID AddNode(const Station *st);
524 void RemoveNode(NodeID id);
526 protected:
527 friend class LinkGraph::ConstNode;
528 friend class LinkGraph::Node;
529 friend const SaveLoad *GetLinkGraphDesc();
530 friend const SaveLoad *GetLinkGraphJobDesc();
531 friend void SaveLoad_LinkGraph(LinkGraph &lg);
533 CargoID cargo; ///< Cargo of this component's link graph.
534 Date last_compression; ///< Last time the capacities and supplies were compressed.
535 NodeVector nodes; ///< Nodes in the component.
536 EdgeMatrix edges; ///< Edges in the component.
539 #define FOR_ALL_LINK_GRAPHS(var) FOR_ALL_ITEMS_FROM(LinkGraph, link_graph_index, var, 0)
541 #endif /* LINKGRAPH_H */