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

49 lines
2.3 KiB
Diff

# UNDF: UNDF-2026-000001008
--- a/src/simutrans/simhalt.cc
+++ b/src/simutrans/simhalt.cc
@@ -3295,14 +3295,19 @@
// iterate over all lines (public halt: all lines, other: only player's lines)
for( uint8 i=pl_min; i<pl_max; i++ ) {
if( player_t *player = welt->get_player(i) ) {
player->simlinemgmt.get_lines(simline_t::line, &check_line);
for(linehandle_t const j : check_line ) {
// only add unknown lines
- if( !registered_lines.is_contained(j) && j->count_convoys() > 0 ) {
+ // Use a hash set for O(1) membership test instead of
+ // vector_tpl::is_contained O(R) linear scan per line.
+ // Previously O(L * R) where L = lines, R = registered lines.
+ if( !registered_lines_set.get(j.get_id()) && j->count_convoys() > 0 ) {
for(schedule_entry_t const& k : j->get_schedule()->entries ) {
if( get_halt(k.pos, player) == self ) {
registered_lines.append(j);
+ registered_lines_set.put(j.get_id(), true);
break;
}
}
}
}
}
}
- // iterate over all convoys
- for(convoihandle_t const cnv : welt->convoys()) {
- // only check lineless convoys which have matching ownership and which are not yet registered
- if( !cnv->get_line().is_bound() && (public_halt || cnv->get_owner()==get_owner()) && !registered_convoys.is_contained(cnv) ) {
+ // iterate over all convoys
+ // Build a temporary hash set of registered convoy IDs for O(1) lookup.
+ // Previously registered_convoys.is_contained(cnv) was O(R) linear scan
+ // called for every convoy in the world = O(C * R) total.
+ inthashtable_tpl<uint16, bool> registered_cnv_set;
+ for(convoihandle_t const cnv : registered_convoys) {
+ registered_cnv_set.put(cnv.get_id(), true);
+ }
+ for(convoihandle_t const cnv : welt->convoys()) {
+ // only check lineless convoys which have matching ownership and which are not yet registered
+ if( !cnv->get_line().is_bound() && (public_halt || cnv->get_owner()==get_owner()) && !registered_cnv_set.get(cnv.get_id()) ) {
if( const schedule_t *const schedule = cnv->get_schedule() ) {
for(schedule_entry_t const& k : schedule->entries) {
if (get_halt(k.pos, cnv->get_owner()) == self) {
registered_convoys.append(cnv);
+ registered_cnv_set.put(cnv.get_id(), true);
break;
}
}