Change link graph join and compression times to use scaled tick counter
This commit is contained in:
@@ -2489,7 +2489,9 @@ DEF_CONSOLE_CMD(ConMergeLinkgraphJobsAsap)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) lgj->ShiftJoinDate((EconTime::CurDateTicks() - lgj->JoinDateTicks()).base() / DAY_TICKS);
|
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
|
||||||
|
lgj->SetJoinTick(_scaled_tick_counter);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2736,13 +2738,9 @@ DEF_CONSOLE_CMD(ConDumpLinkgraphJobs)
|
|||||||
|
|
||||||
IConsolePrintF(CC_DEFAULT, PRINTF_SIZE " link graph jobs", LinkGraphJob::GetNumItems());
|
IConsolePrintF(CC_DEFAULT, PRINTF_SIZE " link graph jobs", LinkGraphJob::GetNumItems());
|
||||||
for (const LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
|
for (const LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
|
||||||
EconTime::YearMonthDay start_ymd = EconTime::ConvertDateToYMD(lgj->StartDateTicks().ToDate());
|
IConsolePrintF(CC_DEFAULT, " Job: %5u, nodes: %u, cost: " OTTD_PRINTF64U ", started: %d, ends in: %d, duration: %d",
|
||||||
EconTime::YearMonthDay join_ymd = EconTime::ConvertDateToYMD(lgj->JoinDateTicks().ToDate());
|
|
||||||
IConsolePrintF(CC_DEFAULT, " Job: %5u, nodes: %u, cost: " OTTD_PRINTF64U ", start: (" OTTD_PRINTF64 ", %4i-%02i-%02i, %i), end: (" OTTD_PRINTF64 ", %4i-%02i-%02i, %i), duration: " OTTD_PRINTF64,
|
|
||||||
lgj->index, lgj->Graph().Size(), lgj->Graph().CalculateCostEstimate(),
|
lgj->index, lgj->Graph().Size(), lgj->Graph().CalculateCostEstimate(),
|
||||||
lgj->StartDateTicks().base(), start_ymd.year.base(), start_ymd.month + 1, start_ymd.day, lgj->StartDateTicks().ToDateFractRemainder(),
|
(int)(lgj->StartTick() - _scaled_tick_counter), (int)(lgj->JoinTick() - _scaled_tick_counter), (int)(lgj->JoinTick() - lgj->StartTick()));
|
||||||
lgj->JoinDateTicks().base(), join_ymd.year.base(), join_ymd.month + 1, join_ymd.day, lgj->JoinDateTicks().ToDateFractRemainder(),
|
|
||||||
(lgj->JoinDateTicks() - lgj->StartDateTicks()).base());
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -67,9 +67,6 @@ void CheckStateTicksWrap()
|
|||||||
|
|
||||||
extern void AdjustVehicleStateTicksBase(StateTicksDelta delta);
|
extern void AdjustVehicleStateTicksBase(StateTicksDelta delta);
|
||||||
AdjustVehicleStateTicksBase(-tick_adjust);
|
AdjustVehicleStateTicksBase(-tick_adjust);
|
||||||
|
|
||||||
extern void AdjustLinkGraphStateTicksBase(StateTicksDelta delta);
|
|
||||||
AdjustLinkGraphStateTicksBase(-tick_adjust);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1623,8 +1623,6 @@ void OnTick_Trees();
|
|||||||
void OnTick_Station();
|
void OnTick_Station();
|
||||||
void OnTick_Industry();
|
void OnTick_Industry();
|
||||||
|
|
||||||
void OnTick_LinkGraph();
|
|
||||||
|
|
||||||
void CallLandscapeTick()
|
void CallLandscapeTick()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -1639,6 +1637,4 @@ void CallLandscapeTick()
|
|||||||
OnTick_Industry();
|
OnTick_Industry();
|
||||||
RecordSyncEvent(NSRE_INDUSTRY);
|
RecordSyncEvent(NSRE_INDUSTRY);
|
||||||
}
|
}
|
||||||
|
|
||||||
OnTick_LinkGraph();
|
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ void FlowMapper::Run(LinkGraphJob &job) const
|
|||||||
/* Scale by time the graph has been running without being compressed. Add 1 to avoid
|
/* Scale by time the graph has been running without being compressed. Add 1 to avoid
|
||||||
* division by 0 if spawn date == last compression date. This matches
|
* division by 0 if spawn date == last compression date. This matches
|
||||||
* LinkGraph::Monthly(). */
|
* LinkGraph::Monthly(). */
|
||||||
uint runtime = (uint)Clamp<StateTicksDelta>(DateTicksToStateTicks(job.StartDateTicks()) - job.LastCompression() + 1, 1, UINT32_MAX).base();
|
uint runtime = (uint)Clamp<ScaledTickCounter>(job.StartTick() - job.LastCompression() + 1, 1, UINT32_MAX);
|
||||||
for (auto &it : flows) {
|
for (auto &it : flows) {
|
||||||
it.ScaleToMonthly(runtime);
|
it.ScaleToMonthly(runtime);
|
||||||
}
|
}
|
||||||
|
@@ -54,7 +54,7 @@ void LinkGraph::ShiftDates(DateDelta interval)
|
|||||||
|
|
||||||
void LinkGraph::Compress()
|
void LinkGraph::Compress()
|
||||||
{
|
{
|
||||||
this->last_compression = (_state_ticks.base() + this->last_compression.base()) / 2;
|
this->last_compression = (_scaled_tick_counter + this->last_compression) / 2;
|
||||||
for (NodeID node1 = 0; node1 < this->Size(); ++node1) {
|
for (NodeID node1 = 0; node1 < this->Size(); ++node1) {
|
||||||
this->nodes[node1].supply /= 2;
|
this->nodes[node1].supply /= 2;
|
||||||
}
|
}
|
||||||
@@ -79,8 +79,8 @@ void LinkGraph::Compress()
|
|||||||
*/
|
*/
|
||||||
void LinkGraph::Merge(LinkGraph *other)
|
void LinkGraph::Merge(LinkGraph *other)
|
||||||
{
|
{
|
||||||
uint32_t age = ClampTo<uint32_t>(CeilDivT<int64_t>(_state_ticks.base() - this->last_compression.base() + 1, DAY_TICKS));
|
uint32_t age = ClampTo<uint32_t>(CeilDivT<int64_t>(_scaled_tick_counter - this->last_compression + 1, DAY_TICKS));
|
||||||
uint32_t other_age = ClampTo<uint32_t>(CeilDivT<int64_t>(_state_ticks.base() - other->last_compression.base() + 1, DAY_TICKS));
|
uint32_t other_age = ClampTo<uint32_t>(CeilDivT<int64_t>(_scaled_tick_counter - other->last_compression + 1, DAY_TICKS));
|
||||||
NodeID first = this->Size();
|
NodeID first = this->Size();
|
||||||
this->nodes.reserve(first + other->Size());
|
this->nodes.reserve(first + other->Size());
|
||||||
for (NodeID node1 = 0; node1 < other->Size(); ++node1) {
|
for (NodeID node1 = 0; node1 < other->Size(); ++node1) {
|
||||||
@@ -266,23 +266,26 @@ void LinkGraph::Init(uint size)
|
|||||||
this->nodes.resize(size);
|
this->nodes.resize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdjustLinkGraphStateTicksBase(StateTicksDelta delta)
|
void LinkGraphFixupAfterLoad(bool compression_was_date)
|
||||||
{
|
|
||||||
for (LinkGraph *lg : LinkGraph::Iterate()) lg->last_compression += delta;
|
|
||||||
|
|
||||||
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
|
|
||||||
LinkGraph *lg = &(const_cast<LinkGraph &>(lgj->Graph()));
|
|
||||||
lg->last_compression += delta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinkGraphFixupLastCompressionAfterLoad()
|
|
||||||
{
|
{
|
||||||
/* last_compression was previously a Date, change it to a StateTicks */
|
/* last_compression was previously a Date, change it to a StateTicks */
|
||||||
for (LinkGraph *lg : LinkGraph::Iterate()) lg->last_compression = DateToStateTicks((EconTime::Date)lg->last_compression.base());
|
for (LinkGraph *lg : LinkGraph::Iterate()) {
|
||||||
|
if (compression_was_date) lg->last_compression = DateToStateTicks((EconTime::Date)lg->last_compression).base();
|
||||||
|
lg->last_compression -= _state_ticks.base();
|
||||||
|
lg->last_compression += _scaled_tick_counter;
|
||||||
|
}
|
||||||
|
|
||||||
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
|
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) {
|
||||||
LinkGraph *lg = &(const_cast<LinkGraph &>(lgj->Graph()));
|
LinkGraph *lg = &(const_cast<LinkGraph &>(lgj->Graph()));
|
||||||
lg->last_compression = DateToStateTicks((EconTime::Date)lg->last_compression.base());
|
if (compression_was_date) lg->last_compression = DateToStateTicks((EconTime::Date)lg->last_compression).base();
|
||||||
|
lg->last_compression -= _state_ticks.base();
|
||||||
|
lg->last_compression += _scaled_tick_counter;
|
||||||
|
|
||||||
|
/* Change start and join ticks from DateTicks to ScaledTickCounter */
|
||||||
|
auto convert = [&](ScaledTickCounter &tick) {
|
||||||
|
tick = (uint64_t)(std::max<int64_t>(0, _scaled_tick_counter + (DateTicksToStateTicks((EconTime::DateTicks)tick) - _state_ticks).base()));
|
||||||
|
};
|
||||||
|
convert(lgj->join_tick);
|
||||||
|
convert(lgj->start_tick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -290,7 +290,7 @@ public:
|
|||||||
static constexpr DateDelta STALE_LINK_DEPOT_TIMEOUT = 1024;
|
static constexpr DateDelta STALE_LINK_DEPOT_TIMEOUT = 1024;
|
||||||
|
|
||||||
/** Minimum number of ticks between subsequent compressions of a LG. */
|
/** Minimum number of ticks between subsequent compressions of a LG. */
|
||||||
static constexpr StateTicksDelta COMPRESSION_INTERVAL = 256 * DAY_TICKS;
|
static constexpr ScaledTickCounter COMPRESSION_INTERVAL = 256 * DAY_TICKS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scale a value from a link graph of age orig_age for usage in one of age
|
* Scale a value from a link graph of age orig_age for usage in one of age
|
||||||
@@ -311,7 +311,7 @@ public:
|
|||||||
* Real constructor.
|
* Real constructor.
|
||||||
* @param cargo Cargo the link graph is about.
|
* @param cargo Cargo the link graph is about.
|
||||||
*/
|
*/
|
||||||
LinkGraph(CargoID cargo) : cargo(cargo), last_compression(_state_ticks) {}
|
LinkGraph(CargoID cargo) : cargo(cargo), last_compression(_scaled_tick_counter) {}
|
||||||
|
|
||||||
void Init(uint size);
|
void Init(uint size);
|
||||||
void ShiftDates(DateDelta interval);
|
void ShiftDates(DateDelta interval);
|
||||||
@@ -350,7 +350,7 @@ public:
|
|||||||
* Get date of last compression.
|
* Get date of last compression.
|
||||||
* @return Date of last compression.
|
* @return Date of last compression.
|
||||||
*/
|
*/
|
||||||
inline StateTicks LastCompression() const { return this->last_compression; }
|
inline ScaledTickCounter LastCompression() const { return this->last_compression; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the cargo ID this component's link graph refers to.
|
* Get the cargo ID this component's link graph refers to.
|
||||||
@@ -365,7 +365,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline uint Monthly(uint base) const
|
inline uint Monthly(uint base) const
|
||||||
{
|
{
|
||||||
return (uint)((static_cast<uint64_t>(base) * 30 * DAY_TICKS * DayLengthFactor()) / std::max<uint64_t>((_state_ticks - this->last_compression).base(), DAY_TICKS));
|
return (uint)((static_cast<uint64_t>(base) * 30 * DAY_TICKS * DayLengthFactor()) / std::max<uint64_t>(_scaled_tick_counter - this->last_compression, DAY_TICKS));
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeID AddNode(const Station *st);
|
NodeID AddNode(const Station *st);
|
||||||
@@ -392,11 +392,10 @@ protected:
|
|||||||
friend upstream_sl::SlLinkgraphNode;
|
friend upstream_sl::SlLinkgraphNode;
|
||||||
friend upstream_sl::SlLinkgraphEdge;
|
friend upstream_sl::SlLinkgraphEdge;
|
||||||
|
|
||||||
friend void AdjustLinkGraphStateTicksBase(StateTicksDelta delta);
|
friend void LinkGraphFixupAfterLoad(bool compression_was_date);
|
||||||
friend void LinkGraphFixupLastCompressionAfterLoad();
|
|
||||||
|
|
||||||
CargoID cargo; ///< Cargo of this component's link graph.
|
CargoID cargo; ///< Cargo of this component's link graph.
|
||||||
StateTicks last_compression; ///< Last time the capacities and supplies were compressed.
|
ScaledTickCounter last_compression; ///< Last time the capacities and supplies were compressed.
|
||||||
NodeVector nodes; ///< Nodes in the component.
|
NodeVector nodes; ///< Nodes in the component.
|
||||||
EdgeMatrix edges; ///< Edges in the component.
|
EdgeMatrix edges; ///< Edges in the component.
|
||||||
|
|
||||||
|
@@ -26,10 +26,10 @@ INSTANTIATE_POOL_METHODS(LinkGraphJob)
|
|||||||
*/
|
*/
|
||||||
/* static */ Path *Path::invalid_path = new Path(INVALID_NODE, true);
|
/* static */ Path *Path::invalid_path = new Path(INVALID_NODE, true);
|
||||||
|
|
||||||
static EconTime::DateTicks GetLinkGraphJobJoinDateTicks(uint duration_multiplier)
|
static ScaledTickCounter GetLinkGraphJobJoinTick(uint duration_multiplier)
|
||||||
{
|
{
|
||||||
DateTicksDelta ticks = (_settings_game.linkgraph.recalc_time * DAY_TICKS * duration_multiplier) / (SECONDS_PER_DAY * _settings_game.economy.day_length_factor);
|
ScaledTickCounter ticks = (_settings_game.linkgraph.recalc_time * DAY_TICKS * duration_multiplier) / SECONDS_PER_DAY;
|
||||||
return ticks + EconTime::CurDateTicks();
|
return ticks + _scaled_tick_counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,8 +43,8 @@ LinkGraphJob::LinkGraphJob(const LinkGraph &orig, uint duration_multiplier) :
|
|||||||
* This is on purpose. */
|
* This is on purpose. */
|
||||||
link_graph(orig),
|
link_graph(orig),
|
||||||
settings(_settings_game.linkgraph),
|
settings(_settings_game.linkgraph),
|
||||||
join_date_ticks(GetLinkGraphJobJoinDateTicks(duration_multiplier)),
|
join_tick(GetLinkGraphJobJoinTick(duration_multiplier)),
|
||||||
start_date_ticks(EconTime::CurDateTicks()),
|
start_tick(_scaled_tick_counter),
|
||||||
job_completed(false),
|
job_completed(false),
|
||||||
job_aborted(false)
|
job_aborted(false)
|
||||||
{
|
{
|
||||||
|
@@ -131,6 +131,7 @@ private:
|
|||||||
friend SaveLoadTable GetLinkGraphJobDesc();
|
friend SaveLoadTable GetLinkGraphJobDesc();
|
||||||
friend upstream_sl::SaveLoadTable upstream_sl::GetLinkGraphJobDesc();
|
friend upstream_sl::SaveLoadTable upstream_sl::GetLinkGraphJobDesc();
|
||||||
friend void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj);
|
friend void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj);
|
||||||
|
friend void LinkGraphFixupAfterLoad(bool compression_was_date);
|
||||||
friend class LinkGraphSchedule;
|
friend class LinkGraphSchedule;
|
||||||
friend class LinkGraphJobGroup;
|
friend class LinkGraphJobGroup;
|
||||||
|
|
||||||
@@ -139,8 +140,8 @@ protected:
|
|||||||
|
|
||||||
std::shared_ptr<LinkGraphJobGroup> group; ///< Job group thread the job is running in or nullptr if it's running in the main thread.
|
std::shared_ptr<LinkGraphJobGroup> group; ///< Job group thread the job is running in or nullptr if it's running in the main thread.
|
||||||
const LinkGraphSettings settings; ///< Copy of _settings_game.linkgraph at spawn time.
|
const LinkGraphSettings settings; ///< Copy of _settings_game.linkgraph at spawn time.
|
||||||
EconTime::DateTicks join_date_ticks; ///< Date when the job is to be joined.
|
ScaledTickCounter join_tick; ///< Tick when the job is to be joined.
|
||||||
EconTime::DateTicks start_date_ticks; ///< Date when the job was started.
|
ScaledTickCounter start_tick; ///< Tick when the job was started.
|
||||||
NodeAnnotationVector nodes; ///< Extra node data necessary for link graph calculation.
|
NodeAnnotationVector nodes; ///< Extra node data necessary for link graph calculation.
|
||||||
EdgeAnnotationVector edges; ///< Edge data necessary for link graph calculation.
|
EdgeAnnotationVector edges; ///< Edge data necessary for link graph calculation.
|
||||||
std::atomic<bool> job_completed; ///< Is the job still running. This is accessed by multiple threads and reads may be stale.
|
std::atomic<bool> job_completed; ///< Is the job still running. This is accessed by multiple threads and reads may be stale.
|
||||||
@@ -263,7 +264,7 @@ public:
|
|||||||
* settings have to be brutally const-casted in order to populate them.
|
* settings have to be brutally const-casted in order to populate them.
|
||||||
*/
|
*/
|
||||||
LinkGraphJob() : settings(_settings_game.linkgraph),
|
LinkGraphJob() : settings(_settings_game.linkgraph),
|
||||||
join_date_ticks(EconTime::INVALID_DATE_TICKS), start_date_ticks(EconTime::INVALID_DATE_TICKS), job_completed(false), job_aborted(false) {}
|
join_tick(0), start_tick(0), job_completed(false), job_aborted(false) {}
|
||||||
|
|
||||||
LinkGraphJob(const LinkGraph &orig, uint duration_multiplier);
|
LinkGraphJob(const LinkGraph &orig, uint duration_multiplier);
|
||||||
~LinkGraphJob();
|
~LinkGraphJob();
|
||||||
@@ -298,29 +299,25 @@ public:
|
|||||||
* @param tick_offset Optional number of ticks to add to the current date
|
* @param tick_offset Optional number of ticks to add to the current date
|
||||||
* @return True if job should be finished by now, false if not.
|
* @return True if job should be finished by now, false if not.
|
||||||
*/
|
*/
|
||||||
inline bool IsScheduledToBeJoined(int tick_offset = 0) const { return this->join_date_ticks <= EconTime::CurDateTicks() + tick_offset; }
|
inline bool IsScheduledToBeJoined(int tick_offset = 0) const { return this->join_tick <= _scaled_tick_counter + tick_offset; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the date when the job should be finished.
|
* Get the tick when the job should be finished.
|
||||||
* @return Join date.
|
* @return Join date.
|
||||||
*/
|
*/
|
||||||
inline EconTime::DateTicks JoinDateTicks() const { return join_date_ticks; }
|
inline ScaledTickCounter JoinTick() const { return this->join_tick; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the date when the job was started.
|
* Get the tick when the job was started.
|
||||||
* @return Start date.
|
* @return Start date.
|
||||||
*/
|
*/
|
||||||
inline EconTime::DateTicks StartDateTicks() const { return start_date_ticks; }
|
inline ScaledTickCounter StartTick() const { return this->start_tick; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the start and join dates on date cheating.
|
* Set the tick when the job should be joined.
|
||||||
* @param interval Number of days to add.
|
* @return Start date.
|
||||||
*/
|
*/
|
||||||
inline void ShiftJoinDate(DateDelta interval)
|
inline void SetJoinTick(ScaledTickCounter tick) { this->join_tick = tick; }
|
||||||
{
|
|
||||||
this->join_date_ticks += DateDeltaToDateTicksDelta(interval);
|
|
||||||
this->start_date_ticks += DateDeltaToDateTicksDelta(interval);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the link graph settings for this component.
|
* Get the link graph settings for this component.
|
||||||
@@ -351,7 +348,7 @@ public:
|
|||||||
* Get the state tick when the underlying link graph was last compressed.
|
* Get the state tick when the underlying link graph was last compressed.
|
||||||
* @return Compression date.
|
* @return Compression date.
|
||||||
*/
|
*/
|
||||||
inline StateTicks LastCompression() const { return this->link_graph.LastCompression(); }
|
inline ScaledTickCounter LastCompression() const { return this->link_graph.LastCompression(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the ID of the underlying link graph.
|
* Get the ID of the underlying link graph.
|
||||||
|
@@ -81,14 +81,14 @@ void LinkGraphSchedule::SpawnNext()
|
|||||||
uint duration_multiplier = CeilDivT<uint64_t>(lg->Size(), 75);
|
uint duration_multiplier = CeilDivT<uint64_t>(lg->Size(), 75);
|
||||||
std::unique_ptr<LinkGraphJob> job(new LinkGraphJob(*lg, duration_multiplier));
|
std::unique_ptr<LinkGraphJob> job(new LinkGraphJob(*lg, duration_multiplier));
|
||||||
jobs_to_execute.emplace_back(job.get(), cost);
|
jobs_to_execute.emplace_back(job.get(), cost);
|
||||||
if (this->running.empty() || job->JoinDateTicks() >= this->running.back()->JoinDateTicks()) {
|
if (this->running.empty() || job->JoinTick() >= this->running.back()->JoinTick()) {
|
||||||
this->running.push_back(std::move(job));
|
this->running.push_back(std::move(job));
|
||||||
DEBUG(linkgraph, 3, "LinkGraphSchedule::SpawnNext(): Running job: id: %u, nodes: %u, cost: " OTTD_PRINTF64U ", duration_multiplier: %u",
|
DEBUG(linkgraph, 3, "LinkGraphSchedule::SpawnNext(): Running job: id: %u, nodes: %u, cost: " OTTD_PRINTF64U ", duration_multiplier: %u",
|
||||||
lg->index, lg->Size(), cost, duration_multiplier);
|
lg->index, lg->Size(), cost, duration_multiplier);
|
||||||
} else {
|
} else {
|
||||||
// find right place to insert
|
// find right place to insert
|
||||||
auto iter = std::upper_bound(this->running.begin(), this->running.end(), job->JoinDateTicks(), [](EconTime::DateTicks a, const std::unique_ptr<LinkGraphJob> &b) {
|
auto iter = std::upper_bound(this->running.begin(), this->running.end(), job->JoinTick(), [](ScaledTickCounter a, const std::unique_ptr<LinkGraphJob> &b) {
|
||||||
return a < b->JoinDateTicks();
|
return a < b->JoinTick();
|
||||||
});
|
});
|
||||||
this->running.insert(iter, std::move(job));
|
this->running.insert(iter, std::move(job));
|
||||||
DEBUG(linkgraph, 3, "LinkGraphSchedule::SpawnNext(): Running job (re-ordering): id: %u, nodes: %u, cost: " OTTD_PRINTF64U ", duration_multiplier: %u",
|
DEBUG(linkgraph, 3, "LinkGraphSchedule::SpawnNext(): Running job (re-ordering): id: %u, nodes: %u, cost: " OTTD_PRINTF64U ", duration_multiplier: %u",
|
||||||
@@ -203,7 +203,6 @@ void LinkGraphSchedule::SpawnAll()
|
|||||||
void LinkGraphSchedule::ShiftDates(DateDelta interval)
|
void LinkGraphSchedule::ShiftDates(DateDelta interval)
|
||||||
{
|
{
|
||||||
for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(interval);
|
for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(interval);
|
||||||
for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) lgj->ShiftJoinDate(interval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -276,16 +275,16 @@ void LinkGraphJobGroup::JoinThread()
|
|||||||
const uint thread_budget = 200000;
|
const uint thread_budget = 200000;
|
||||||
|
|
||||||
std::sort(jobs.begin(), jobs.end(), [](const JobInfo &a, const JobInfo &b) {
|
std::sort(jobs.begin(), jobs.end(), [](const JobInfo &a, const JobInfo &b) {
|
||||||
return std::make_pair(a.job->JoinDateTicks(), a.cost_estimate) < std::make_pair(b.job->JoinDateTicks(), b.cost_estimate);
|
return std::make_pair(a.job->JoinTick(), a.cost_estimate) < std::make_pair(b.job->JoinTick(), b.cost_estimate);
|
||||||
});
|
});
|
||||||
|
|
||||||
std::vector<LinkGraphJob *> bucket;
|
std::vector<LinkGraphJob *> bucket;
|
||||||
uint bucket_cost = 0;
|
uint bucket_cost = 0;
|
||||||
EconTime::DateTicks bucket_join_date = 0;
|
ScaledTickCounter bucket_join_tick = 0;
|
||||||
auto flush_bucket = [&]() {
|
auto flush_bucket = [&]() {
|
||||||
if (!bucket_cost) return;
|
if (!bucket_cost) return;
|
||||||
DEBUG(linkgraph, 2, "LinkGraphJobGroup::ExecuteJobSet: Creating Job Group: jobs: " PRINTF_SIZE ", cost: %u, join after: " OTTD_PRINTF64,
|
DEBUG(linkgraph, 2, "LinkGraphJobGroup::ExecuteJobSet: Creating Job Group: jobs: " PRINTF_SIZE ", cost: %u, join after: " OTTD_PRINTF64,
|
||||||
bucket.size(), bucket_cost, (bucket_join_date - EconTime::CurDateTicks()).base());
|
bucket.size(), bucket_cost, bucket_join_tick - _scaled_tick_counter);
|
||||||
auto group = std::make_shared<LinkGraphJobGroup>(constructor_token(), std::move(bucket));
|
auto group = std::make_shared<LinkGraphJobGroup>(constructor_token(), std::move(bucket));
|
||||||
group->SpawnThread();
|
group->SpawnThread();
|
||||||
bucket_cost = 0;
|
bucket_cost = 0;
|
||||||
@@ -293,8 +292,8 @@ void LinkGraphJobGroup::JoinThread()
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (JobInfo &it : jobs) {
|
for (JobInfo &it : jobs) {
|
||||||
if (bucket_cost && (bucket_join_date != it.job->JoinDateTicks() || (bucket_cost + it.cost_estimate > thread_budget))) flush_bucket();
|
if (bucket_cost && (bucket_join_tick != it.job->JoinTick() || (bucket_cost + it.cost_estimate > thread_budget))) flush_bucket();
|
||||||
bucket_join_date = it.job->JoinDateTicks();
|
bucket_join_tick = it.job->JoinTick();
|
||||||
bucket.push_back(it.job);
|
bucket.push_back(it.job);
|
||||||
bucket_cost += it.cost_estimate;
|
bucket_cost += it.cost_estimate;
|
||||||
}
|
}
|
||||||
@@ -305,10 +304,10 @@ LinkGraphJobGroup::JobInfo::JobInfo(LinkGraphJob *job) :
|
|||||||
job(job), cost_estimate(job->Graph().CalculateCostEstimate()) { }
|
job(job), cost_estimate(job->Graph().CalculateCostEstimate()) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pause the game if in 2 _date_fract ticks, we would do a join with the next
|
* Pause the game if in 2 ticks, we would do a join with the next
|
||||||
* link graph job, but it is still running.
|
* link graph job, but it is still running.
|
||||||
* The check is done 2 _date_fract ticks early instead of 1, as in multiplayer
|
* The check is done 2 ticks early instead of 1, as in multiplayer
|
||||||
* calls to DoCommandP are executed after a delay of 1 _date_fract tick.
|
* calls to DoCommandP are executed after a delay of 1 tick.
|
||||||
* If we previously paused, unpause if the job is now ready to be joined with.
|
* If we previously paused, unpause if the job is now ready to be joined with.
|
||||||
*/
|
*/
|
||||||
void StateGameLoop_LinkGraphPauseControl()
|
void StateGameLoop_LinkGraphPauseControl()
|
||||||
@@ -318,19 +317,14 @@ void StateGameLoop_LinkGraphPauseControl()
|
|||||||
if (!LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) {
|
if (!LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) {
|
||||||
DoCommandP(0, PM_PAUSED_LINK_GRAPH, 0, CMD_PAUSE);
|
DoCommandP(0, PM_PAUSED_LINK_GRAPH, 0, CMD_PAUSE);
|
||||||
}
|
}
|
||||||
} else if (_pause_mode == PM_UNPAUSED && TickSkipCounter() == 0) {
|
} else if (_pause_mode == PM_UNPAUSED) {
|
||||||
if (DayLengthFactor() == 1) {
|
int interval = _settings_game.linkgraph.recalc_interval * DAY_TICKS / SECONDS_PER_DAY;
|
||||||
if (EconTime::CurDateFract() != LinkGraphSchedule::SPAWN_JOIN_TICK - 2) return;
|
int offset = _scaled_tick_counter % interval;
|
||||||
if (EconTime::CurDate().base() % _settings_game.linkgraph.recalc_interval != (_settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY) / 2) return;
|
if (offset == (interval / 2) - 2) {
|
||||||
} else {
|
/* perform check 2 ticks before we would join */
|
||||||
int date_ticks = (EconTime::CurDateTicks() - (LinkGraphSchedule::SPAWN_JOIN_TICK - 2)).base();
|
if (LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) {
|
||||||
int interval = std::max<int>(2, (_settings_game.linkgraph.recalc_interval * DAY_TICKS / (SECONDS_PER_DAY * DayLengthFactor())));
|
DoCommandP(0, PM_PAUSED_LINK_GRAPH, 1, CMD_PAUSE);
|
||||||
if (date_ticks % interval != interval / 2) return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* perform check one _date_fract tick before we would join */
|
|
||||||
if (LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) {
|
|
||||||
DoCommandP(0, PM_PAUSED_LINK_GRAPH, 1, CMD_PAUSE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -353,16 +347,8 @@ void AfterLoad_LinkGraphPauseControl()
|
|||||||
*/
|
*/
|
||||||
void OnTick_LinkGraph()
|
void OnTick_LinkGraph()
|
||||||
{
|
{
|
||||||
int offset;
|
int interval = _settings_game.linkgraph.recalc_interval * DAY_TICKS / SECONDS_PER_DAY;
|
||||||
int interval;
|
int offset = _scaled_tick_counter % interval;
|
||||||
if (DayLengthFactor() == 1) {
|
|
||||||
if (EconTime::CurDateFract() != LinkGraphSchedule::SPAWN_JOIN_TICK) return;
|
|
||||||
interval = _settings_game.linkgraph.recalc_interval / SECONDS_PER_DAY;
|
|
||||||
offset = EconTime::CurDate().base() % interval;
|
|
||||||
} else {
|
|
||||||
interval = std::max<int>(2, (_settings_game.linkgraph.recalc_interval * DAY_TICKS / (SECONDS_PER_DAY * DayLengthFactor())));
|
|
||||||
offset = (EconTime::CurDateTicks() - LinkGraphSchedule::SPAWN_JOIN_TICK).base() % interval;
|
|
||||||
}
|
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
LinkGraphSchedule::instance.SpawnNext();
|
LinkGraphSchedule::instance.SpawnNext();
|
||||||
} else if (offset == interval / 2) {
|
} else if (offset == interval / 2) {
|
||||||
|
@@ -120,6 +120,7 @@ void MusicLoop();
|
|||||||
void CallWindowGameTickEvent();
|
void CallWindowGameTickEvent();
|
||||||
bool HandleBootstrap();
|
bool HandleBootstrap();
|
||||||
void OnTick_Companies(bool main_tick);
|
void OnTick_Companies(bool main_tick);
|
||||||
|
void OnTick_LinkGraph();
|
||||||
|
|
||||||
extern void AfterLoadCompanyStats();
|
extern void AfterLoadCompanyStats();
|
||||||
extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY);
|
extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY);
|
||||||
@@ -2180,6 +2181,7 @@ void StateGameLoop()
|
|||||||
CallLandscapeTick();
|
CallLandscapeTick();
|
||||||
OnTick_Companies(true);
|
OnTick_Companies(true);
|
||||||
}
|
}
|
||||||
|
OnTick_LinkGraph();
|
||||||
TimerManager<TimerGameTick>::Elapsed(1);
|
TimerManager<TimerGameTick>::Elapsed(1);
|
||||||
BasePersistentStorageArray::SwitchMode(PSM_LEAVE_GAMELOOP);
|
BasePersistentStorageArray::SwitchMode(PSM_LEAVE_GAMELOOP);
|
||||||
|
|
||||||
|
@@ -934,10 +934,10 @@ bool AfterLoadGame()
|
|||||||
_settings_game.linkgraph.recalc_time *= SECONDS_PER_DAY;
|
_settings_game.linkgraph.recalc_time *= SECONDS_PER_DAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert link graph last compression from date to scaled ticks. */
|
/* Convert link graph last compression from date to scaled tick counter, or state ticks to scaled ticks. */
|
||||||
if (SlXvIsFeatureMissing(XSLFI_LINKGRAPH_DAY_SCALE, 4)) {
|
if (SlXvIsFeatureMissing(XSLFI_LINKGRAPH_DAY_SCALE, 6)) {
|
||||||
extern void LinkGraphFixupLastCompressionAfterLoad();
|
extern void LinkGraphFixupAfterLoad(bool compression_was_date);
|
||||||
LinkGraphFixupLastCompressionAfterLoad();
|
LinkGraphFixupAfterLoad(SlXvIsFeatureMissing(XSLFI_LINKGRAPH_DAY_SCALE, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the sprites */
|
/* Load the sprites */
|
||||||
|
@@ -180,7 +180,7 @@ SaveLoadTable GetLinkGraphJobDesc()
|
|||||||
SLE_VAR2(LinkGraphJob, "linkgraph.demand_size", settings.demand_size, SLE_UINT8),
|
SLE_VAR2(LinkGraphJob, "linkgraph.demand_size", settings.demand_size, SLE_UINT8),
|
||||||
SLE_VAR2(LinkGraphJob, "linkgraph.short_path_saturation", settings.short_path_saturation, SLE_UINT8),
|
SLE_VAR2(LinkGraphJob, "linkgraph.short_path_saturation", settings.short_path_saturation, SLE_UINT8),
|
||||||
|
|
||||||
SLE_VAR2(LinkGraphJob, "join_date", join_date_ticks, SLE_FILE_I32 | SLE_VAR_I64),
|
SLE_VAR2(LinkGraphJob, "join_date", join_tick, SLE_FILE_I32 | SLE_VAR_U64),
|
||||||
SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16),
|
SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16),
|
||||||
SLEG_STRUCT("linkgraph", SlLinkgraphJobProxy),
|
SLEG_STRUCT("linkgraph", SlLinkgraphJobProxy),
|
||||||
};
|
};
|
||||||
|
@@ -109,7 +109,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
|||||||
{ XSLFI_EXTRA_LARGE_MAP, XSCF_NULL, 0, 1, "extra_large_map", nullptr, nullptr, nullptr },
|
{ XSLFI_EXTRA_LARGE_MAP, XSCF_NULL, 0, 1, "extra_large_map", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_REVERSE_AT_WAYPOINT, XSCF_NULL, 1, 1, "reverse_at_waypoint", nullptr, nullptr, nullptr },
|
{ XSLFI_REVERSE_AT_WAYPOINT, XSCF_NULL, 1, 1, "reverse_at_waypoint", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_VEH_LIFETIME_PROFIT, XSCF_NULL, 1, 1, "veh_lifetime_profit", nullptr, nullptr, nullptr },
|
{ XSLFI_VEH_LIFETIME_PROFIT, XSCF_NULL, 1, 1, "veh_lifetime_profit", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_LINKGRAPH_DAY_SCALE, XSCF_NULL, 5, 5, "linkgraph_day_scale", nullptr, nullptr, nullptr },
|
{ XSLFI_LINKGRAPH_DAY_SCALE, XSCF_NULL, 6, 6, "linkgraph_day_scale", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_TEMPLATE_REPLACEMENT, XSCF_NULL, 9, 9, "template_replacement", nullptr, nullptr, "TRPL,TMPL" },
|
{ XSLFI_TEMPLATE_REPLACEMENT, XSCF_NULL, 9, 9, "template_replacement", nullptr, nullptr, "TRPL,TMPL" },
|
||||||
{ XSLFI_MORE_RAIL_TYPES, XSCF_NULL, 0, 1, "more_rail_types", nullptr, nullptr, nullptr },
|
{ XSLFI_MORE_RAIL_TYPES, XSCF_NULL, 0, 1, "more_rail_types", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_CARGO_TYPE_ORDERS, XSCF_NULL, 3, 3, "cargo_type_orders", nullptr, nullptr, "ORDX,VEOX" },
|
{ XSLFI_CARGO_TYPE_ORDERS, XSCF_NULL, 3, 3, "cargo_type_orders", nullptr, nullptr, "ORDX,VEOX" },
|
||||||
|
@@ -30,7 +30,8 @@ SaveLoadTable GetLinkGraphDesc()
|
|||||||
{
|
{
|
||||||
static const SaveLoad link_graph_desc[] = {
|
static const SaveLoad link_graph_desc[] = {
|
||||||
SLE_CONDVAR_X(LinkGraph, last_compression, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 0, 3)),
|
SLE_CONDVAR_X(LinkGraph, last_compression, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 0, 3)),
|
||||||
SLE_CONDVAR_X(LinkGraph, last_compression, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 4)),
|
SLE_CONDVAR_X(LinkGraph, last_compression, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 4, 5)),
|
||||||
|
SLE_CONDVAR_X(LinkGraph, last_compression, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 6)),
|
||||||
SLEG_VAR(_num_nodes, SLE_UINT16),
|
SLEG_VAR(_num_nodes, SLE_UINT16),
|
||||||
SLE_VAR(LinkGraph, cargo, SLE_UINT8),
|
SLE_VAR(LinkGraph, cargo, SLE_UINT8),
|
||||||
};
|
};
|
||||||
@@ -39,8 +40,8 @@ SaveLoadTable GetLinkGraphDesc()
|
|||||||
|
|
||||||
void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj)
|
void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj)
|
||||||
{
|
{
|
||||||
lgj->join_date_ticks.edit_base() *= DAY_TICKS;
|
lgj->join_tick *= DAY_TICKS;
|
||||||
lgj->join_date_ticks += LinkGraphSchedule::SPAWN_JOIN_TICK;
|
lgj->join_tick += LinkGraphSchedule::SPAWN_JOIN_TICK;
|
||||||
|
|
||||||
uint recalc_scale;
|
uint recalc_scale;
|
||||||
if (IsSavegameVersionBefore(SLV_LINKGRAPH_SECONDS) && SlXvIsFeatureMissing(XSLFI_LINKGRAPH_DAY_SCALE, 3)) {
|
if (IsSavegameVersionBefore(SLV_LINKGRAPH_SECONDS) && SlXvIsFeatureMissing(XSLFI_LINKGRAPH_DAY_SCALE, 3)) {
|
||||||
@@ -50,7 +51,7 @@ void GetLinkGraphJobDayLengthScaleAfterLoad(LinkGraphJob *lgj)
|
|||||||
/* recalc time is in seconds */
|
/* recalc time is in seconds */
|
||||||
recalc_scale = DAY_TICKS / SECONDS_PER_DAY;
|
recalc_scale = DAY_TICKS / SECONDS_PER_DAY;
|
||||||
}
|
}
|
||||||
lgj->start_date_ticks = lgj->join_date_ticks - (lgj->Settings().recalc_time * recalc_scale);
|
lgj->start_tick = lgj->join_tick - (lgj->Settings().recalc_time * recalc_scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,10 +84,12 @@ SaveLoadTable GetLinkGraphJobDesc()
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SaveLoad job_desc[] = {
|
const SaveLoad job_desc[] = {
|
||||||
SLE_CONDVAR_X(LinkGraphJob, join_date_ticks, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 0, 4)),
|
SLE_CONDVAR_X(LinkGraphJob, join_tick, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 0, 4)),
|
||||||
SLE_CONDVAR_X(LinkGraphJob, join_date_ticks, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 5)),
|
SLE_CONDVAR_X(LinkGraphJob, join_tick, SLE_FILE_I64 | SLE_VAR_U64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 5, 5)),
|
||||||
SLE_CONDVAR_X(LinkGraphJob, start_date_ticks, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 1, 4)),
|
SLE_CONDVAR_X(LinkGraphJob, join_tick, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 6)),
|
||||||
SLE_CONDVAR_X(LinkGraphJob, start_date_ticks, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 5)),
|
SLE_CONDVAR_X(LinkGraphJob, start_tick, SLE_FILE_I32 | SLE_VAR_U64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 1, 4)),
|
||||||
|
SLE_CONDVAR_X(LinkGraphJob, start_tick, SLE_FILE_I64 | SLE_VAR_U64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 5, 5)),
|
||||||
|
SLE_CONDVAR_X(LinkGraphJob, start_tick, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_DAY_SCALE, 6)),
|
||||||
SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16),
|
SLE_VAR(LinkGraphJob, link_graph.index, SLE_UINT16),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -4552,7 +4552,7 @@ void DeleteStaleLinks(Station *from)
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
assert(_state_ticks >= lg->LastCompression());
|
assert(_state_ticks >= lg->LastCompression());
|
||||||
if ((_state_ticks - lg->LastCompression()) > LinkGraph::COMPRESSION_INTERVAL) {
|
if ((_scaled_tick_counter - lg->LastCompression()) > LinkGraph::COMPRESSION_INTERVAL) {
|
||||||
lg->Compress();
|
lg->Compress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user