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.7 KiB
Diff
43 lines
1.7 KiB
Diff
# UNDF: UNDF-2026-000000964
|
|
--- 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>
|
|
|
|
@@ -250,6 +251,7 @@
|
|
|
|
std::list<size_t> openset;
|
|
std::set<size_t> closedset;
|
|
+ std::unordered_set<size_t> opensetMembership;
|
|
openset.push_back(start);
|
|
+ opensetMembership.insert(start);
|
|
|
|
size_t current = start;
|
|
@@ -260,6 +262,7 @@
|
|
current = openset.front(); // front has the lowest cost
|
|
openset.pop_front();
|
|
+ opensetMembership.erase(current);
|
|
|
|
if (current == goal)
|
|
break;
|
|
@@ -274,7 +277,7 @@
|
|
size_t dest = edge.index;
|
|
float tentativeG = gScore[current] + edge.cost;
|
|
- bool isInOpenSet = std::find(openset.begin(), openset.end(), dest) != openset.end();
|
|
+ bool isInOpenSet = opensetMembership.count(dest) > 0;
|
|
if (!isInOpenSet || tentativeG < gScore[dest])
|
|
{
|
|
graphParent[dest] = current;
|
|
@@ -282,6 +285,7 @@
|
|
fScore[dest] = tentativeG + costAStar(mPathgrid->mPoints[dest], mPathgrid->mPoints[goal]);
|
|
if (!isInOpenSet)
|
|
{
|
|
+ opensetMembership.insert(dest);
|
|
// add this edge to openset, lowest cost goes to the front
|
|
// TODO: if this causes performance problems a hash table may help
|
|
auto it = openset.begin();
|