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/>.
10 /** @file linkgraphjob.h Declaration of link graph job classes used for cargo distribution. */
12 #ifndef LINKGRAPHJOB_H
13 #define LINKGRAPHJOB_H
15 #include "../thread/thread.h"
16 #include "../core/dyn_arena_alloc.hpp"
17 #include "linkgraph.h"
23 class LinkGraphJobGroup
;
24 typedef std::vector
<Path
*> PathList
;
26 /** Type of the pool for link graph jobs. */
27 typedef Pool
<LinkGraphJob
, LinkGraphJobID
, 32, 0xFFFF> LinkGraphJobPool
;
28 /** The actual pool with link graph jobs. */
29 extern LinkGraphJobPool _link_graph_job_pool
;
32 * Class for calculation jobs to be run on link graphs.
34 class LinkGraphJob
: public LinkGraphJobPool::PoolItem
<&_link_graph_job_pool
> {
37 * Annotation for a link graph edge.
39 struct EdgeAnnotation
{
40 uint demand
; ///< Transport demand between the nodes.
41 uint unsatisfied_demand
; ///< Demand over this edge that hasn't been satisfied yet.
42 uint flow
; ///< Planned flow over this edge.
47 * Annotation for a link graph node.
49 struct NodeAnnotation
{
50 uint undelivered_supply
; ///< Amount of supply that hasn't been distributed yet.
51 PathList paths
; ///< Paths through this node, sorted so that those with flow == 0 are in the back.
52 FlowStatMap flows
; ///< Planned flows to other nodes.
53 void Init(uint supply
);
56 typedef std::vector
<NodeAnnotation
> NodeAnnotationVector
;
57 typedef SmallMatrix
<EdgeAnnotation
> EdgeAnnotationMatrix
;
59 friend const SaveLoad
*GetLinkGraphJobDesc();
60 friend void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob
*lgj
);
61 friend class LinkGraphSchedule
;
62 friend class LinkGraphJobGroup
;
65 const LinkGraph link_graph
; ///< Link graph to by analyzed. Is copied when job is started and mustn't be modified later.
66 std::shared_ptr
<LinkGraphJobGroup
> group
; ///< JOb group thread the job is running in or nullptr if it's running in the main thread.
67 const LinkGraphSettings settings
; ///< Copy of _settings_game.linkgraph at spawn time.
68 Ticks join_date_ticks
; ///< Date when the job is to be joined.
69 Ticks start_date_ticks
; ///< Date when the job was started.
70 NodeAnnotationVector nodes
; ///< Extra node data necessary for link graph calculation.
71 EdgeAnnotationMatrix edges
; ///< Extra edge data necessary for link graph calculation.
72 bool job_completed
; ///< Is the job still running. This is accessed by multiple threads and is permitted to be spuriously incorrect.
73 bool abort_job
; ///< Abort the job at the next available opportunity. This is accessed by multiple threads.
75 void EraseFlows(NodeID from
);
77 void SetJobGroup(std::shared_ptr
<LinkGraphJobGroup
> group
);
81 DynUniformArenaAllocator path_allocator
; ///< Arena allocator used for paths
83 bool IsJobAborted() const;
86 * A job edge. Wraps a link graph edge and an edge annotation. The
87 * annotation can be modified, the edge is constant.
89 class Edge
: public LinkGraph::ConstEdge
{
91 EdgeAnnotation
& anno
; ///< Annotation being wrapped.
95 * @param edge Link graph edge to be wrapped.
96 * @param anno Annotation to be wrapped.
98 Edge(const LinkGraph::BaseEdge
&edge
, EdgeAnnotation
&anno
) :
99 LinkGraph::ConstEdge(edge
), anno(anno
) {}
102 * Get the transport demand between end the points of the edge.
105 uint
Demand() const { return this->anno
.demand
; }
108 * Get the transport demand that hasn't been satisfied by flows, yet.
109 * @return Unsatisfied demand.
111 uint
UnsatisfiedDemand() const { return this->anno
.unsatisfied_demand
; }
114 * Get the total flow on the edge.
117 uint
Flow() const { return this->anno
.flow
; }
121 * @param flow Flow to be added.
123 void AddFlow(uint flow
) { this->anno
.flow
+= flow
; }
127 * @param flow Flow to be removed.
129 void RemoveFlow(uint flow
)
131 assert(flow
<= this->anno
.flow
);
132 this->anno
.flow
-= flow
;
136 * Add some (not yet satisfied) demand.
137 * @param demand Demand to be added.
139 void AddDemand(uint demand
)
141 this->anno
.demand
+= demand
;
142 this->anno
.unsatisfied_demand
+= demand
;
146 * Satisfy some demand.
147 * @param demand Demand to be satisfied.
149 void SatisfyDemand(uint demand
)
151 assert(demand
<= this->anno
.unsatisfied_demand
);
152 this->anno
.unsatisfied_demand
-= demand
;
157 * Iterator for job edges.
159 class EdgeIterator
: public LinkGraph::BaseEdgeIterator
<const LinkGraph::BaseEdge
, Edge
, EdgeIterator
> {
160 EdgeAnnotation
*base_anno
; ///< Array of annotations to be (indirectly) iterated.
164 * @param base Array of edges to be iterated.
165 * @param base_anno Array of annotations to be iterated.
166 * @param current Start offset of iteration.
168 EdgeIterator(const LinkGraph::BaseEdge
*base
, EdgeAnnotation
*base_anno
, NodeID current
) :
169 LinkGraph::BaseEdgeIterator
<const LinkGraph::BaseEdge
, Edge
, EdgeIterator
>(base
, current
),
170 base_anno(base_anno
) {}
174 * @return Pair of the edge currently pointed to and the ID of its
177 SmallPair
<NodeID
, Edge
> operator*() const
179 return SmallPair
<NodeID
, Edge
>(this->current
, Edge(this->base
[this->current
], this->base_anno
[this->current
]));
183 * Dereference. Has to be repeated here as operator* is different than
184 * in LinkGraph::EdgeWrapper.
185 * @return Fake pointer to pair of NodeID/Edge.
187 FakePointer
operator->() const {
188 return FakePointer(this->operator*());
193 * Link graph job node. Wraps a constant link graph node and a modifiable
196 class Node
: public LinkGraph::ConstNode
{
198 NodeAnnotation
& node_anno
; ///< Annotation being wrapped.
199 EdgeAnnotation
*edge_annos
; ///< Edge annotations belonging to this node.
204 * @param lgj Job to take the node from.
205 * @param node ID of the node.
207 Node(LinkGraphJob
*lgj
, NodeID node
) :
208 LinkGraph::ConstNode(&lgj
->link_graph
, node
),
209 node_anno(lgj
->nodes
[node
]), edge_annos(lgj
->edges
[node
])
213 * Retrieve an edge starting at this node. Mind that this returns an
214 * object, not a reference.
215 * @param to Remote end of the edge.
216 * @return Edge between this node and "to".
218 Edge
operator[](NodeID to
) const { return Edge(this->edges
[to
], this->edge_annos
[to
]); }
221 * Iterator for the "begin" of the edge array. Only edges with capacity
222 * are iterated. The others are skipped.
223 * @return Iterator pointing to the first edge.
225 EdgeIterator
Begin() const { return EdgeIterator(this->edges
, this->edge_annos
, index
); }
228 * Iterator for the "end" of the edge array. Only edges with capacity
229 * are iterated. The others are skipped.
230 * @return Iterator pointing beyond the last edge.
232 EdgeIterator
End() const { return EdgeIterator(this->edges
, this->edge_annos
, INVALID_NODE
); }
235 * Get amount of supply that hasn't been delivered, yet.
236 * @return Undelivered supply.
238 uint
UndeliveredSupply() const { return this->node_anno
.undelivered_supply
; }
241 * Get the flows running through this node.
244 FlowStatMap
&Flows() { return this->node_anno
.flows
; }
247 * Get a constant version of the flows running through this node.
250 const FlowStatMap
&Flows() const { return this->node_anno
.flows
; }
253 * Get the paths this node is part of. Paths are always expected to be
254 * sorted so that those with flow == 0 are in the back of the list.
257 PathList
&Paths() { return this->node_anno
.paths
; }
260 * Get a constant version of the paths this node is part of.
263 const PathList
&Paths() const { return this->node_anno
.paths
; }
266 * Deliver some supply, adding demand to the respective edge.
267 * @param to Destination for supply.
268 * @param amount Amount of supply to be delivered.
270 void DeliverSupply(NodeID to
, uint amount
)
272 this->node_anno
.undelivered_supply
-= amount
;
273 (*this)[to
].AddDemand(amount
);
278 * Bare constructor, only for save/load. link_graph, join_date and actually
279 * settings have to be brutally const-casted in order to populate them.
281 LinkGraphJob() : settings(_settings_game
.linkgraph
),
282 join_date_ticks(INVALID_DATE
), start_date_ticks(INVALID_DATE
), job_completed(false) {}
284 LinkGraphJob(const LinkGraph
&orig
, uint duration_multiplier
);
290 bool IsJobCompleted() const;
294 * Check if job is supposed to be finished.
295 * @param tick_offset Optional number of ticks to add to the current date
296 * @return True if job should be finished by now, false if not.
298 inline bool IsFinished(int tick_offset
= 0) const { return this->join_date_ticks
<= (_date
* DAY_TICKS
) + _date_fract
+ tick_offset
; }
301 * Get the date when the job should be finished.
304 inline Ticks
JoinDateTicks() const { return join_date_ticks
; }
307 * Get the date when the job was started.
308 * @return Start date.
310 inline Ticks
StartDateTicks() const { return start_date_ticks
; }
313 * Change the join date on date cheating.
314 * @param interval Number of days to add.
316 inline void ShiftJoinDate(int interval
) { this->join_date_ticks
+= interval
* DAY_TICKS
; }
319 * Get the link graph settings for this component.
322 inline const LinkGraphSettings
&Settings() const { return this->settings
; }
325 * Get a node abstraction with the specified id.
326 * @param num ID of the node.
327 * @return the Requested node.
329 inline Node
operator[](NodeID num
) { return Node(this, num
); }
332 * Get the size of the underlying link graph.
335 inline uint
Size() const { return this->link_graph
.Size(); }
338 * Get the cargo of the underlying link graph.
341 inline CargoID
Cargo() const { return this->link_graph
.Cargo(); }
344 * Get the date when the underlying link graph was last compressed.
345 * @return Compression date.
347 inline Date
LastCompression() const { return this->link_graph
.LastCompression(); }
350 * Get the ID of the underlying link graph.
351 * @return Link graph ID.
353 inline LinkGraphID
LinkGraphIndex() const { return this->link_graph
.index
; }
356 * Get a reference to the underlying link graph. Only use this for save/load.
357 * @return Link graph.
359 inline const LinkGraph
&Graph() const { return this->link_graph
; }
362 #define FOR_ALL_LINK_GRAPH_JOBS(var) FOR_ALL_ITEMS_FROM(LinkGraphJob, link_graph_job_index, var, 0)
365 * A leg of a path in the link graph. Paths can form trees by being "forked".
369 static Path
*invalid_path
;
371 Path(NodeID n
, bool source
= false);
373 /** Get the node this leg passes. */
374 inline NodeID
GetNode() const { return this->node
; }
376 /** Get the overall origin of the path. */
377 inline NodeID
GetOrigin() const { return this->origin
; }
379 /** Get the parent leg of this one. */
380 inline Path
*GetParent() { return this->parent
; }
382 /** Get the overall capacity of the path. */
383 inline uint
GetCapacity() const { return this->capacity
; }
385 /** Get the free capacity of the path. */
386 inline int GetFreeCapacity() const { return this->free_capacity
; }
389 * Get ratio of free * 16 (so that we get fewer 0) /
390 * max(total capacity, 1) (so that we don't divide by 0).
391 * @param free Free capacity.
392 * @param total Total capacity.
393 * @return free * 16 / max(total, 1).
395 inline static int GetCapacityRatio(int free
, uint total
)
397 return Clamp(free
, PATH_CAP_MIN_FREE
, PATH_CAP_MAX_FREE
) * PATH_CAP_MULTIPLIER
/ max(total
, 1U);
401 * Get capacity ratio of this path.
402 * @return free capacity * 16 / (total capacity + 1).
404 inline int GetCapacityRatio() const
406 return Path::GetCapacityRatio(this->free_capacity
, this->capacity
);
409 /** Get the overall distance of the path. */
410 inline uint
GetDistance() const { return this->distance
; }
412 /** Reduce the flow on this leg only by the specified amount. */
413 inline void ReduceFlow(uint f
) { this->flow
-= f
; }
415 /** Increase the flow on this leg only by the specified amount. */
416 inline void AddFlow(uint f
) { this->flow
+= f
; }
418 /** Get the flow on this leg. */
419 inline uint
GetFlow() const { return this->flow
; }
421 /** Get the number of "forked off" child legs of this one. */
422 inline uint
GetNumChildren() const { return this->num_children
; }
425 * Detach this path from its parent.
429 if (this->parent
!= nullptr) {
430 this->parent
->num_children
--;
431 this->parent
= nullptr;
435 uint
AddFlow(uint f
, LinkGraphJob
&job
, uint max_saturation
);
436 void Fork(Path
*base
, uint cap
, int free_cap
, uint dist
);
441 * Some boundaries to clamp agains in order to avoid integer overflows.
443 enum PathCapacityBoundaries
{
444 PATH_CAP_MULTIPLIER
= 16,
445 PATH_CAP_MIN_FREE
= (INT_MIN
+ 1) / PATH_CAP_MULTIPLIER
,
446 PATH_CAP_MAX_FREE
= (INT_MAX
- 1) / PATH_CAP_MULTIPLIER
449 uint distance
; ///< Sum(distance of all legs up to this one).
450 uint capacity
; ///< This capacity is min(capacity) fom all edges.
451 int free_capacity
; ///< This capacity is min(edge.capacity - edge.flow) for the current run of Dijkstra.
452 uint flow
; ///< Flow the current run of the mcf solver assigns.
453 NodeID node
; ///< Link graph node this leg passes.
454 NodeID origin
; ///< Link graph node this path originates from.
455 uint num_children
; ///< Number of child legs that have been forked from this path.
456 Path
*parent
; ///< Parent leg of this one.
459 #endif /* LINKGRAPHJOB_H */