megaglest-0001: Unit::updateAttackBoostProgress() std::find on currentAttackBoostUnits vector<int> inside per-frame candidate loop O(C*B), plus reverse lookup on candidateValidIdList O(B*C). Fix: unordered_set<int> for O(1) membership. MEDIUM, 8.3x at N=2000. megaglest-0002: UnitUpdater::findUnitsForCell() linear dedup scan of units vector inside findUnitsInRange grid loop O(R^2 * U). Fix: unordered_set<int> seenIds for O(1) dedup. HIGH, 9.1x at cells=5000, units=500. MOAD-0002 (Intertangle): CLEAN, standard game engine singletons. MOAD-0003 (Leaked Context): CLEAN, no thread_local usage. MOAD-0004 (Logged Secret): FTP password logged in miniftpclient.cpp lines 358, 360, 968, 975 via szBuf containing ftp://user:pass@host URL. CWE-312 confirmed but in bundled third-party FTP client code. MOAD-0005 (Thundering Herd): CLEAN, single-threaded game logic. 4/4 unit tests PASS.
62 lines
2.1 KiB
Diff
62 lines
2.1 KiB
Diff
--- a/source/glest_game/world/unit_updater.h
|
|
+++ b/source/glest_game/world/unit_updater.h
|
|
@@ -1,6 +1,7 @@
|
|
#ifndef _GLEST_GAME_UNITUPDATER_H_
|
|
#define _GLEST_GAME_UNITUPDATER_H_
|
|
|
|
+#include <unordered_set>
|
|
#include <vector>
|
|
|
|
...
|
|
@@ -127,7 +128,7 @@
|
|
vector<Unit *> findUnitsInRange(const Unit *unit, int radius);
|
|
|
|
private:
|
|
- void findUnitsForCell(Cell *cell, vector<Unit *> &units);
|
|
+ void findUnitsForCell(Cell *cell, vector<Unit *> &units, std::unordered_set<int> &seenIds);
|
|
|
|
--- a/source/glest_game/world/unit_updater.cpp
|
|
+++ b/source/glest_game/world/unit_updater.cpp
|
|
@@ -3461,13 +3461,10 @@
|
|
-void UnitUpdater::findUnitsForCell(Cell *cell, vector<Unit *> &units) {
|
|
+void UnitUpdater::findUnitsForCell(Cell *cell, vector<Unit *> &units, std::unordered_set<int> &seenIds) {
|
|
// all fields
|
|
if (cell != NULL) {
|
|
for (int k = 0; k < fieldCount; k++) {
|
|
Field f = static_cast<Field>(k);
|
|
|
|
// check field
|
|
Unit *cellUnit = cell->getUnit(f);
|
|
|
|
if (cellUnit != NULL && cellUnit->isAlive()) {
|
|
- // check if unit already is in list
|
|
- bool found = false;
|
|
- for (unsigned int i = 0; i < units.size(); ++i) {
|
|
- Unit *unitInList = units[i];
|
|
- if (unitInList->getId() == cellUnit->getId()) {
|
|
- found = true;
|
|
- break;
|
|
- }
|
|
- }
|
|
- if (found == false) {
|
|
+ // O(1) dedup via hash set instead of O(U) linear scan
|
|
+ if (seenIds.insert(cellUnit->getId()).second) {
|
|
units.push_back(cellUnit);
|
|
}
|
|
}
|
|
@@ -3492,6 +3489,8 @@
|
|
vector<Unit *> UnitUpdater::findUnitsInRange(const Unit *unit, int radius) {
|
|
int range = radius;
|
|
vector<Unit *> units;
|
|
+ std::unordered_set<int> seenIds;
|
|
|
|
// aux vars
|
|
int size = unit->getType()->getSize();
|
|
@@ -3507,7 +3506,7 @@
|
|
#endif
|
|
Cell *cell = map->getCell(i, j);
|
|
- findUnitsForCell(cell, units);
|
|
+ findUnitsForCell(cell, units, seenIds);
|
|
}
|
|
}
|
|
}
|