OpenTTD Source: src/linkgraph/linkgraphjob.h Source File

OpenTTD Source 15.0-RC2

linkgraphjob.h
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#ifndef LINKGRAPHJOB_H
11#define LINKGRAPHJOB_H
12
13#include "../thread.h"
14#include "linkgraph.h"
15#include <atomic>
16
17class LinkGraphJob;
18class Path;
19typedef std::list<Path *> PathList;
20
22 using LinkGraphJobPool = Pool<LinkGraphJob, LinkGraphJobID, 32>;
24extern LinkGraphJobPool _link_graph_job_pool;
25
29 class LinkGraphJob : public LinkGraphJobPool::PoolItem<&_link_graph_job_pool>{
30public:
34 struct DemandAnnotation {
35 uint demand = 0;
36 uint unsatisfied_demand = 0;
37 };
38
42 struct EdgeAnnotation {
43 const LinkGraph::BaseEdge &base;
44 uint flow = 0;
45
46 EdgeAnnotation(const LinkGraph::BaseEdge &base) : base(base) {}
47
52 uint Flow() const { return this->flow; }
53
58 void AddFlow(uint flow) { this->flow += flow; }
59
64 void RemoveFlow(uint flow)
65 {
66 assert(flow <= this->flow);
67 this->flow -= flow;
68 }
69
70 friend inline bool operator <(NodeID dest, const EdgeAnnotation &rhs)
71 {
72 return dest < rhs.base.dest_node;
73 }
74 };
75
79 struct NodeAnnotation {
80 const LinkGraph::BaseNode &base;
81
82 uint undelivered_supply = 0;
83 PathList paths{};
84 FlowStatMap flows{};
85
86 std::vector<EdgeAnnotation> edges{};
87 std::vector<DemandAnnotation> demands{};
88
89 NodeAnnotation(const LinkGraph::BaseNode &node, size_t size) : base(node), undelivered_supply(node.supply)
90 {
91 this->edges.reserve(node.edges.size());
92 for (auto &e : node.edges) this->edges.emplace_back(e);
93 this->demands.resize(size);
94 }
95
101 EdgeAnnotation &operator[](NodeID to)
102 {
103 auto it = std::ranges::find_if(this->edges, [=] (const EdgeAnnotation &e) { return e.base.dest_node == to; });
104 assert(it != this->edges.end());
105 return *it;
106 }
107
113 const EdgeAnnotation &operator[](NodeID to) const
114 {
115 auto it = std::ranges::find_if(this->edges, [=] (const EdgeAnnotation &e) { return e.base.dest_node == to; });
116 assert(it != this->edges.end());
117 return *it;
118 }
119
124 uint DemandTo(NodeID to) const { return this->demands[to].demand; }
125
130 uint UnsatisfiedDemandTo(NodeID to) const { return this->demands[to].unsatisfied_demand; }
131
136 void SatisfyDemandTo(NodeID to, uint demand)
137 {
138 assert(demand <= this->demands[to].unsatisfied_demand);
139 this->demands[to].unsatisfied_demand -= demand;
140 }
141
147 void DeliverSupply(NodeID to, uint amount)
148 {
149 this->undelivered_supply -= amount;
150 this->demands[to].demand += amount;
151 this->demands[to].unsatisfied_demand += amount;
152 }
153 };
154
155private:
156 typedef std::vector<NodeAnnotation> NodeAnnotationVector;
157
158 friend SaveLoadTable GetLinkGraphJobDesc();
159 friend class LinkGraphSchedule;
160
161protected:
162 const LinkGraph link_graph;
163 const LinkGraphSettings settings;
164 std::thread thread{};
165 TimerGameEconomy::Date join_date = EconomyTime::INVALID_DATE;
166 NodeAnnotationVector nodes{};
167 std::atomic<bool> job_completed = false;
168 std::atomic<bool> job_aborted = false;
169
170 void EraseFlows(StationID from);
171 void JoinThread();
172 void SpawnThread();
173
174public:
179 LinkGraphJob() : settings(_settings_game.linkgraph) {}
180
181 LinkGraphJob(const LinkGraph &orig);
182 ~LinkGraphJob();
183
184 void Init();
185
191 inline bool IsJobCompleted() const { return this->job_completed.load(std::memory_order_acquire); }
192
198 inline bool IsJobAborted() const { return this->job_aborted.load(std::memory_order_acquire); }
199
206 inline void AbortJob() { this->job_aborted.store(true, std::memory_order_release); }
207
212 inline bool IsScheduledToBeJoined() const { return this->join_date <= TimerGameEconomy::date; }
213
218 inline TimerGameEconomy::Date JoinDate() const { return join_date; }
219
224 inline void ShiftJoinDate(TimerGameEconomy::Date interval) { this->join_date += interval; }
225
230 inline const LinkGraphSettings &Settings() const { return this->settings; }
231
237 inline NodeAnnotation &operator[](NodeID num) { return this->nodes[num]; }
238
243 inline NodeID Size() const { return this->link_graph.Size(); }
244
249 inline CargoType Cargo() const { return this->link_graph.Cargo(); }
250
255 inline TimerGameEconomy::Date LastCompression() const { return this->link_graph.LastCompression(); }
256
261 inline LinkGraphID LinkGraphIndex() const { return this->link_graph.index; }
262
267 inline const LinkGraph &Graph() const { return this->link_graph; }
268};
269
273 class Path {
274public:
275 static Path *invalid_path;
276
277 Path(NodeID n, bool source = false);
278 virtual ~Path() = default;
279
281 inline NodeID GetNode() const { return this->node; }
282
284 inline NodeID GetOrigin() const { return this->origin; }
285
287 inline Path *GetParent() { return this->parent; }
288
290 inline uint GetCapacity() const { return this->capacity; }
291
293 inline int GetFreeCapacity() const { return this->free_capacity; }
294
302 static inline int GetCapacityRatio(int free, uint total)
303 {
304 return Clamp(free, PATH_CAP_MIN_FREE, PATH_CAP_MAX_FREE) * PATH_CAP_MULTIPLIER / std::max(total, 1U);
305 }
306
311 inline int GetCapacityRatio() const
312 {
313 return Path::GetCapacityRatio(this->free_capacity, this->capacity);
314 }
315
317 inline uint GetDistance() const { return this->distance; }
318
320 inline void ReduceFlow(uint f) { this->flow -= f; }
321
323 inline void AddFlow(uint f) { this->flow += f; }
324
326 inline uint GetFlow() const { return this->flow; }
327
329 inline uint GetNumChildren() const { return this->num_children; }
330
334 inline void Detach()
335 {
336 if (this->parent != nullptr) {
337 this->parent->num_children--;
338 this->parent = nullptr;
339 }
340 }
341
342 uint AddFlow(uint f, LinkGraphJob &job, uint max_saturation);
343 void Fork(Path *base, uint cap, int free_cap, uint dist);
344
345protected:
346
347 /*
348 * Some boundaries to clamp against in order to avoid integer overflows.
349 */
350 static constexpr int PATH_CAP_MULTIPLIER = 16;
351 static constexpr int PATH_CAP_MIN_FREE = (INT_MIN + 1) / PATH_CAP_MULTIPLIER;
352 static constexpr int PATH_CAP_MAX_FREE = (INT_MAX - 1) / PATH_CAP_MULTIPLIER;
353
354 uint distance = 0;
355 uint capacity = 0;
356 int free_capacity = 0;
357 uint flow = 0;
358 NodeID node = INVALID_NODE;
359 NodeID origin = INVALID_NODE;
360 uint num_children = 0;
361 Path *parent = nullptr;
362};
363
364#endif /* LINKGRAPHJOB_H */
CargoType
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:21
FlowStatMap
Flow descriptions by origin stations.
Definition station_base.h:149
LinkGraphJob
Class for calculation jobs to be run on link graphs.
Definition linkgraphjob.h:29
LinkGraphJob::nodes
NodeAnnotationVector nodes
Extra node data necessary for link graph calculation.
Definition linkgraphjob.h:166
LinkGraphJob::job_completed
std::atomic< bool > job_completed
Is the job still running. This is accessed by multiple threads and reads may be stale.
Definition linkgraphjob.h:167
LinkGraphJob::JoinDate
TimerGameEconomy::Date JoinDate() const
Get the date when the job should be finished.
Definition linkgraphjob.h:218
LinkGraphJob::AbortJob
void AbortJob()
Abort job.
Definition linkgraphjob.h:206
LinkGraphJob::~LinkGraphJob
~LinkGraphJob()
Join the link graph job and destroy it.
Definition linkgraphjob.cpp:86
LinkGraphJob::operator[]
NodeAnnotation & operator[](NodeID num)
Get a node abstraction with the specified id.
Definition linkgraphjob.h:237
LinkGraphJob::join_date
TimerGameEconomy::Date join_date
Date when the job is to be joined.
Definition linkgraphjob.h:165
LinkGraphJob::job_aborted
std::atomic< bool > job_aborted
Has the job been aborted. This is accessed by multiple threads and reads may be stale.
Definition linkgraphjob.h:168
LinkGraphJob::LastCompression
TimerGameEconomy::Date LastCompression() const
Get the date when the underlying link graph was last compressed.
Definition linkgraphjob.h:255
LinkGraphJob::LinkGraphJob
LinkGraphJob()
Bare constructor, only for save/load.
Definition linkgraphjob.h:179
LinkGraphJob::LinkGraphIndex
LinkGraphID LinkGraphIndex() const
Get the ID of the underlying link graph.
Definition linkgraphjob.h:261
LinkGraphJob::IsJobAborted
bool IsJobAborted() const
Check if job has been aborted.
Definition linkgraphjob.h:198
LinkGraphJob::Init
void Init()
Initialize the link graph job: Resize nodes and edges and populate them.
Definition linkgraphjob.cpp:182
LinkGraphJob::SpawnThread
void SpawnThread()
Spawn a thread if possible and run the link graph job in the thread.
Definition linkgraphjob.cpp:59
LinkGraphJob::Settings
const LinkGraphSettings & Settings() const
Get the link graph settings for this component.
Definition linkgraphjob.h:230
LinkGraphJob::settings
const LinkGraphSettings settings
Copy of _settings_game.linkgraph at spawn time.
Definition linkgraphjob.h:163
LinkGraphJob::Cargo
CargoType Cargo() const
Get the cargo of the underlying link graph.
Definition linkgraphjob.h:249
LinkGraphJob::Graph
const LinkGraph & Graph() const
Get a reference to the underlying link graph.
Definition linkgraphjob.h:267
LinkGraphJob::IsScheduledToBeJoined
bool IsScheduledToBeJoined() const
Check if job is supposed to be finished.
Definition linkgraphjob.h:212
LinkGraphJob::IsJobCompleted
bool IsJobCompleted() const
Check if job has actually finished.
Definition linkgraphjob.h:191
LinkGraphJob::EraseFlows
void EraseFlows(StationID from)
Erase all flows originating at a specific station.
Definition linkgraphjob.cpp:48
LinkGraphJob::Size
NodeID Size() const
Get the size of the underlying link graph.
Definition linkgraphjob.h:243
LinkGraphJob::link_graph
const LinkGraph link_graph
Link graph to by analyzed. Is copied when job is started and mustn't be modified later.
Definition linkgraphjob.h:162
LinkGraphJob::GetLinkGraphJobDesc
friend SaveLoadTable GetLinkGraphJobDesc()
Get a SaveLoad array for a link graph job.
Definition linkgraph_sl.cpp:180
LinkGraphJob::ShiftJoinDate
void ShiftJoinDate(TimerGameEconomy::Date interval)
Change the join date on date cheating.
Definition linkgraphjob.h:224
LinkGraphJob::JoinThread
void JoinThread()
Join the calling thread with this job's thread if threading is enabled.
Definition linkgraphjob.cpp:76
LinkGraphJob::thread
std::thread thread
Thread the job is running in or a default-constructed thread if it's running in the main thread.
Definition linkgraphjob.h:164
LinkGraphSchedule
Definition linkgraphschedule.h:36
LinkGraph
A connected component of a link graph.
Definition linkgraph.h:37
LinkGraph::LastCompression
TimerGameEconomy::Date LastCompression() const
Get date of last compression.
Definition linkgraph.h:236
LinkGraph::Size
NodeID Size() const
Get the current size of the component.
Definition linkgraph.h:230
LinkGraph::Cargo
CargoType Cargo() const
Get the cargo type this component's link graph refers to.
Definition linkgraph.h:242
Path
A leg of a path in the link graph.
Definition linkgraphjob.h:273
Path::GetOrigin
NodeID GetOrigin() const
Get the overall origin of the path.
Definition linkgraphjob.h:284
Path::AddFlow
void AddFlow(uint f)
Increase the flow on this leg only by the specified amount.
Definition linkgraphjob.h:323
Path::invalid_path
static Path * invalid_path
Static instance of an invalid path.
Definition linkgraphjob.h:275
Path::origin
NodeID origin
Link graph node this path originates from.
Definition linkgraphjob.h:359
Path::num_children
uint num_children
Number of child legs that have been forked from this path.
Definition linkgraphjob.h:360
Path::Detach
void Detach()
Detach this path from its parent.
Definition linkgraphjob.h:334
Path::GetFreeCapacity
int GetFreeCapacity() const
Get the free capacity of the path.
Definition linkgraphjob.h:293
Path::GetFlow
uint GetFlow() const
Get the flow on this leg.
Definition linkgraphjob.h:326
Path::GetCapacityRatio
static int GetCapacityRatio(int free, uint total)
Get ratio of free * 16 (so that we get fewer 0) / max(total capacity, 1) (so that we don't divide by ...
Definition linkgraphjob.h:302
Path::flow
uint flow
Flow the current run of the mcf solver assigns.
Definition linkgraphjob.h:357
Path::distance
uint distance
Sum(distance of all legs up to this one).
Definition linkgraphjob.h:354
Path::GetNode
NodeID GetNode() const
Get the node this leg passes.
Definition linkgraphjob.h:281
Path::GetCapacityRatio
int GetCapacityRatio() const
Get capacity ratio of this path.
Definition linkgraphjob.h:311
Path::Fork
void Fork(Path *base, uint cap, int free_cap, uint dist)
Add this path as a new child to the given base path, thus making this path a "fork" of the base path.
Definition linkgraphjob.cpp:199
Path::node
NodeID node
Link graph node this leg passes.
Definition linkgraphjob.h:358
Path::GetCapacity
uint GetCapacity() const
Get the overall capacity of the path.
Definition linkgraphjob.h:290
Path::GetNumChildren
uint GetNumChildren() const
Get the number of "forked off" child legs of this one.
Definition linkgraphjob.h:329
Path::ReduceFlow
void ReduceFlow(uint f)
Reduce the flow on this leg only by the specified amount.
Definition linkgraphjob.h:320
Path::GetParent
Path * GetParent()
Get the parent leg of this one.
Definition linkgraphjob.h:287
Path::GetDistance
uint GetDistance() const
Get the overall distance of the path.
Definition linkgraphjob.h:317
Path::capacity
uint capacity
This capacity is min(capacity) fom all edges.
Definition linkgraphjob.h:355
Path::parent
Path * parent
Parent leg of this one.
Definition linkgraphjob.h:361
Path::free_capacity
int free_capacity
This capacity is min(edge.capacity - edge.flow) for the current run of Dijkstra.
Definition linkgraphjob.h:356
TimerGameConst< struct Economy >::INVALID_DATE
static constexpr TimerGame< struct Economy >::Date INVALID_DATE
Representation of an invalid date.
Definition timer_game_common.h:193
TimerGameEconomy::date
static Date date
Current date in days (day counter).
Definition timer_game_economy.h:38
linkgraph.h
Declaration of link graph classes used for cargo distribution.
_link_graph_job_pool
LinkGraphJobPool _link_graph_job_pool
The actual pool with link graph jobs.
Clamp
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
SaveLoadTable
std::span< const struct SaveLoad > SaveLoadTable
A table of SaveLoad entries.
Definition saveload.h:530
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
LinkGraphJob::DemandAnnotation
Demand between two nodes.
Definition linkgraphjob.h:34
LinkGraphJob::DemandAnnotation::unsatisfied_demand
uint unsatisfied_demand
Demand over this edge that hasn't been satisfied yet.
Definition linkgraphjob.h:36
LinkGraphJob::DemandAnnotation::demand
uint demand
Transport demand between the nodes.
Definition linkgraphjob.h:35
LinkGraphJob::EdgeAnnotation
Annotation for a link graph edge.
Definition linkgraphjob.h:42
LinkGraphJob::EdgeAnnotation::base
const LinkGraph::BaseEdge & base
Reference to the edge that is annotated.
Definition linkgraphjob.h:43
LinkGraphJob::EdgeAnnotation::Flow
uint Flow() const
Get the total flow on the edge.
Definition linkgraphjob.h:52
LinkGraphJob::EdgeAnnotation::AddFlow
void AddFlow(uint flow)
Add some flow.
Definition linkgraphjob.h:58
LinkGraphJob::EdgeAnnotation::RemoveFlow
void RemoveFlow(uint flow)
Remove some flow.
Definition linkgraphjob.h:64
LinkGraphJob::EdgeAnnotation::flow
uint flow
Planned flow over this edge.
Definition linkgraphjob.h:44
LinkGraphJob::NodeAnnotation
Annotation for a link graph node.
Definition linkgraphjob.h:79
LinkGraphJob::NodeAnnotation::undelivered_supply
uint undelivered_supply
Amount of supply that hasn't been distributed yet.
Definition linkgraphjob.h:82
LinkGraphJob::NodeAnnotation::base
const LinkGraph::BaseNode & base
Reference to the node that is annotated.
Definition linkgraphjob.h:80
LinkGraphJob::NodeAnnotation::edges
std::vector< EdgeAnnotation > edges
Annotations for all edges originating at this node.
Definition linkgraphjob.h:86
LinkGraphJob::NodeAnnotation::paths
PathList paths
Paths through this node, sorted so that those with flow == 0 are in the back.
Definition linkgraphjob.h:83
LinkGraphJob::NodeAnnotation::DeliverSupply
void DeliverSupply(NodeID to, uint amount)
Deliver some supply, adding demand to the respective edge.
Definition linkgraphjob.h:147
LinkGraphJob::NodeAnnotation::flows
FlowStatMap flows
Planned flows to other nodes.
Definition linkgraphjob.h:84
LinkGraphJob::NodeAnnotation::operator[]
EdgeAnnotation & operator[](NodeID to)
Retrieve an edge starting at this node.
Definition linkgraphjob.h:101
LinkGraphJob::NodeAnnotation::operator[]
const EdgeAnnotation & operator[](NodeID to) const
Retrieve an edge starting at this node.
Definition linkgraphjob.h:113
LinkGraphJob::NodeAnnotation::DemandTo
uint DemandTo(NodeID to) const
Get the transport demand between end the points of the edge.
Definition linkgraphjob.h:124
LinkGraphJob::NodeAnnotation::SatisfyDemandTo
void SatisfyDemandTo(NodeID to, uint demand)
Satisfy some demand.
Definition linkgraphjob.h:136
LinkGraphJob::NodeAnnotation::UnsatisfiedDemandTo
uint UnsatisfiedDemandTo(NodeID to) const
Get the transport demand that hasn't been satisfied by flows, yet.
Definition linkgraphjob.h:130
LinkGraphJob::NodeAnnotation::demands
std::vector< DemandAnnotation > demands
Annotations for the demand to all other nodes.
Definition linkgraphjob.h:87
LinkGraphSettings
Definition settings_type.h:570
LinkGraph::BaseEdge
An edge in the link graph.
Definition linkgraph.h:42
LinkGraph::BaseEdge::dest_node
NodeID dest_node
Destination of the edge.
Definition linkgraph.h:48
LinkGraph::BaseNode
Node of the link graph.
Definition linkgraph.h:90
LinkGraph::BaseNode::edges
std::vector< BaseEdge > edges
Sorted list of outgoing edges from this node.
Definition linkgraph.h:97
PoolID< uint16_t, struct StationIDTag, 64000, 0xFFFF >
Pool::PoolItem
Base class for all PoolItems.
Definition pool_type.hpp:285
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition pool_type.hpp:286
Pool
Base class for all pools.
Definition pool_type.hpp:133
StrongType::Typedef
Templated helper to make a type-safe 'typedef' representing a single POD value.
Definition strong_typedef_type.hpp:130