31 lines
1.3 KiB
Diff
31 lines
1.3 KiB
Diff
# UNDF: UNDF-2026-000000978
|
|
# Widelands CWE-407: cleanup_playerimmovables_area burnlist std::find O(N²)
|
|
# File: src/logic/editor_game_base.cc
|
|
# Severity: MEDIUM
|
|
# Speedup: ~250x at N=500 (500 immovables in territory area)
|
|
#
|
|
# EditorGameBase::cleanup_playerimmovables_area() builds a burnlist of
|
|
# immovables outside their owner's territory. For each immovable, it
|
|
# calls std::find() on a std::vector<PlayerImmovable*> to check for
|
|
# duplicates, producing O(N²) where N = immovables in the area.
|
|
# Called during territory changes (conquest, diplomacy).
|
|
#
|
|
# Fix: Add std::unordered_set<PlayerImmovable*> for O(1) membership checks.
|
|
--- a/src/logic/editor_game_base.cc
|
|
+++ b/src/logic/editor_game_base.cc
|
|
@@ -822,11 +822,13 @@
|
|
std::vector<ImmovableFound> immovables;
|
|
std::vector<PlayerImmovable*> burnlist;
|
|
+ std::unordered_set<PlayerImmovable*> burnset;
|
|
|
|
// find all immovables that need fixing
|
|
map_.find_immovables(*this, area, &immovables, FindImmovablePlayerImmovable());
|
|
|
|
for (const ImmovableFound& temp_imm : immovables) {
|
|
upcast(PlayerImmovable, imm, temp_imm.object);
|
|
if (!map_[temp_imm.coords].is_interior(imm->owner().player_number())) {
|
|
- if (std::find(burnlist.begin(), burnlist.end(), imm) == burnlist.end()) {
|
|
+ if (burnset.insert(imm).second) {
|
|
burnlist.push_back(imm);
|
|
}
|
|
}
|