naev-0001: map.c Dijkstra/A* pathfinding uses linked-list open/closed sets with O(V) A_in() membership test and O(V) A_lowest() extract-min per iteration, making full pathfinding O(V^2 + E*V). Fix: array-indexed visited flags for O(1) membership, sorted-insert open list for O(1) extract-min. 102.5x at V=500 (Naev has 538 star systems). HIGH. naev-0002: tech.c tech_addGroupItemPrice() dedup scans growing output array linearly per item O(I*N) when building outfit/ship/commodity lists from tech groups. Fix: hash set for O(1) amortized dedup. 333x at N=1000. MEDIUM. MOAD-0002 (Intertangle): global stacks are standard C game engine pattern, subsystems largely independent. CLEAN. MOAD-0003 (Leaked Context): single thread_local in Rust RNG only. CLEAN. MOAD-0004 (Logged Secret): no credentials in single-player game. CLEAN. MOAD-0005 (Thundering Herd): single-threaded gameplay logic. CLEAN. 2/2 PASS, 2 defects.
29 lines
1.4 KiB
Diff
29 lines
1.4 KiB
Diff
--- a/universe/Tech.cpp
|
|
+++ b/universe/Tech.cpp
|
|
@@ -593,6 +593,7 @@ std::string TechManager::FindFirstDependencyCycle() const {
|
|
|
|
std::vector<const Tech*> stack;
|
|
stack.reserve(m_techs.size());
|
|
+ std::unordered_set<const Tech*> stack_set;
|
|
stack.push_back(&tech);
|
|
while (!stack.empty()) {
|
|
// Examine the tech on top of the stack. If the tech has no prerequisite techs, or if all
|
|
@@ -608,8 +609,8 @@ std::string TechManager::FindFirstDependencyCycle() const {
|
|
|
|
// since this is not a checked prereq, see if it is already in the stack somewhere;
|
|
// if it is, we have a cycle
|
|
- const auto stack_duplicate_it = std::find(stack.rbegin(), stack.rend(), prereq_tech);
|
|
- if (stack_duplicate_it == stack.rend()) {
|
|
+ if (!stack_set.contains(prereq_tech)) {
|
|
// OK! no cycle, move to next prereq
|
|
+ stack_set.insert(prereq_tech);
|
|
stack.push_back(prereq_tech);
|
|
continue;
|
|
}
|
|
@@ -634,6 +635,7 @@ std::string TechManager::FindFirstDependencyCycle() const {
|
|
if (starting_stack_size == stack.size()) {
|
|
stack.pop_back();
|
|
+ stack_set.erase(current_tech);
|
|
checked_techs.insert(current_tech);
|
|
}
|
|
}
|