openmw-0001: pathgrid.cpp Tarjan SCC std::find(mSCCStack) O(V^2), 2.3x (HIGH) openmw-0002: pathgrid.cpp A* openset std::find O(V*E), 4.4x op-count (HIGH) openmw-0003: cellstore.cpp mMovedRefs std::find O(R*M), 15.6x (MEDIUM) openmw-0004: objectpaging.cpp mMovedRefs std::find O(R*M), 4.9x (MEDIUM) MOAD-0002 (Intertangle): CLEAN, typical game engine global state MOAD-0003 (Leaked Context): CLEAN, no thread_local identity carriers MOAD-0004 (Logged Secret): CLEAN, game engine has no credentials MOAD-0005 (Thundering Herd): CLEAN, no unsynchronized cache patterns 8/8 unit tests PASS.
43 lines
1.4 KiB
Diff
43 lines
1.4 KiB
Diff
# UNDF: UNDF-2026-000000963
|
|
--- a/apps/openmw/mwmechanics/pathgrid.cpp
|
|
+++ b/apps/openmw/mwmechanics/pathgrid.cpp
|
|
@@ -1,6 +1,7 @@
|
|
#include "pathgrid.hpp"
|
|
|
|
#include <algorithm>
|
|
+#include <unordered_set>
|
|
#include <list>
|
|
#include <set>
|
|
|
|
@@ -57,6 +58,7 @@
|
|
int mSCCId = 0;
|
|
size_t mSCCIndex = 0;
|
|
std::vector<size_t> mSCCStack;
|
|
+ std::unordered_set<size_t> mSCCOnStack;
|
|
std::vector<std::pair<size_t, size_t>> mSCCPoint; // first is index, second is lowlink
|
|
|
|
// v is the pathgrid point index (some call them vertices)
|
|
@@ -66,6 +68,7 @@
|
|
mSCCPoint[v].second = mSCCIndex; // lowlink
|
|
mSCCIndex++;
|
|
mSCCStack.push_back(v);
|
|
+ mSCCOnStack.insert(v);
|
|
size_t w;
|
|
|
|
for (const auto& edge : mGraph[v].edges)
|
|
@@ -77,7 +80,7 @@
|
|
mSCCPoint[v].second = std::min(mSCCPoint[v].second, mSCCPoint[w].second);
|
|
}
|
|
- else if (std::find(mSCCStack.begin(), mSCCStack.end(), w) != mSCCStack.end())
|
|
+ else if (mSCCOnStack.count(w))
|
|
mSCCPoint[v].second = std::min(mSCCPoint[v].second, mSCCPoint[w].first);
|
|
}
|
|
|
|
@@ -88,6 +91,7 @@
|
|
{
|
|
w = mSCCStack.back();
|
|
mSCCStack.pop_back();
|
|
+ mSCCOnStack.erase(w);
|
|
mGraph[w].componentId = mSCCId;
|
|
} while (w != v);
|
|
mSCCId++;
|