java-topology/defects/simutrans-0003/patch/simutrans-0003.patch

70 lines
3.2 KiB
Diff

# UNDF: UNDF-2026-000001009
--- a/src/simutrans/simhalt.cc
+++ b/src/simutrans/simhalt.cc
@@ -1222,6 +1222,10 @@
sint32 haltestelle_t::rebuild_connections()
{
// halts which either immediately precede or succeed self halt in serving schedules
static vector_tpl<halthandle_t> consecutive_halts[256];
+ // hash sets for O(1) dedup of consecutive halts (replaces append_unique
+ // linear scan which was O(S^2) per category where S = schedule entries)
+ static inthashtable_tpl<uint16, bool> consecutive_halts_seen[256];
// halts which either immediately precede or succeed self halt in currently processed schedule
static vector_tpl<halthandle_t> consecutive_halts_schedule[256];
+ static inthashtable_tpl<uint16, bool> consecutive_halts_schedule_seen[256];
// remember max number of consecutive halts for one schedule
uint8 max_consecutive_halts_schedule[256];
@@ -1234,6 +1238,8 @@
for( uint8 i=0; i<goods_manager_t::get_max_catg_index(); i++ ){
all_links[i].clear();
consecutive_halts[i].clear();
+ consecutive_halts_seen[i].clear();
}
old_sort_mode = 255; // might result in error in routing
@@ -1296,6 +1302,7 @@
for(uint8 const catg_index : *goods_catg_index) {
if( is_enabled(catg_index) ) {
supported_catg_index.append(catg_index);
previous_halt[catg_index] = self;
consecutive_halts_schedule[catg_index].clear();
+ consecutive_halts_schedule_seen[catg_index].clear();
}
}
@@ -1320,8 +1327,18 @@
if( current_halt == self ) {
// check for consecutive halts which precede self halt
for(uint8 const catg_index : supported_catg_index) {
if( previous_halt[catg_index]!=self ) {
- consecutive_halts[catg_index].append_unique(previous_halt[catg_index]);
- consecutive_halts_schedule[catg_index].append_unique(previous_halt[catg_index]);
+ uint16 halt_id = previous_halt[catg_index].get_id();
+ if( !consecutive_halts_seen[catg_index].get(halt_id) ) {
+ consecutive_halts_seen[catg_index].put(halt_id, true);
+ consecutive_halts[catg_index].append(previous_halt[catg_index]);
+ }
+ if( !consecutive_halts_schedule_seen[catg_index].get(halt_id) ) {
+ consecutive_halts_schedule_seen[catg_index].put(halt_id, true);
+ consecutive_halts_schedule[catg_index].append(previous_halt[catg_index]);
+ }
previous_halt[catg_index] = self;
}
}
@@ -1338,8 +1355,16 @@
if( current_halt->is_enabled(catg_index) ) {
// check for consecutive halts which succeed self halt
if( previous_halt[catg_index] == self ) {
- consecutive_halts[catg_index].append_unique(current_halt);
- consecutive_halts_schedule[catg_index].append_unique(current_halt);
+ uint16 halt_id = current_halt.get_id();
+ if( !consecutive_halts_seen[catg_index].get(halt_id) ) {
+ consecutive_halts_seen[catg_index].put(halt_id, true);
+ consecutive_halts[catg_index].append(current_halt);
+ }
+ if( !consecutive_halts_schedule_seen[catg_index].get(halt_id) ) {
+ consecutive_halts_schedule_seen[catg_index].put(halt_id, true);
+ consecutive_halts_schedule[catg_index].append(current_halt);
+ }
}
previous_halt[catg_index] = current_halt;