72 lines
2.1 KiB
Diff
72 lines
2.1 KiB
Diff
# UNDF: UNDF-2026-000000981
|
|
--- a/src/Navaids/airways.cxx
|
|
+++ b/src/Navaids/airways.cxx
|
|
@@ -607,16 +607,6 @@
|
|
}
|
|
}
|
|
|
|
-/**
|
|
- * Inefficent (linear) helper to find an open node in the heap
|
|
- */
|
|
-static AStarOpenNodeRef
|
|
-findInOpen(const OpenNodeHeap& aHeap, FGPositioned* aPos)
|
|
-{
|
|
- for (unsigned int i=0; i<aHeap.size(); ++i) {
|
|
- if (aHeap[i]->node == aPos) {
|
|
- return aHeap[i];
|
|
- }
|
|
- }
|
|
-
|
|
- return nullptr;
|
|
-}
|
|
|
|
class HeapOrder
|
|
{
|
|
@@ -631,6 +621,7 @@
|
|
bool Airway::Network::search2(FGPositionedRef aStart, FGPositionedRef aDest,
|
|
WayptVec& aRoute)
|
|
{
|
|
typedef set<PositionedID> ClosedNodeSet;
|
|
+ typedef std::unordered_map<FGPositioned*, AStarOpenNodeRef> OpenNodeMap;
|
|
|
|
OpenNodeHeap openNodes;
|
|
ClosedNodeSet closedNodes;
|
|
HeapOrder ordering;
|
|
+ OpenNodeMap openNodeMap; // O(1) lookup replacing linear findInOpen
|
|
|
|
openNodes.push_back(new AStarOpenNode(aStart, 0.0, 0, aDest, nullptr));
|
|
+ openNodeMap[aStart] = openNodes.back();
|
|
|
|
// A* open node iteration
|
|
while (!openNodes.empty()) {
|
|
@@ -648,6 +639,7 @@
|
|
std::pop_heap(openNodes.begin(), openNodes.end(), ordering);
|
|
AStarOpenNodeRef x = openNodes.back();
|
|
FGPositioned* xp = x->node;
|
|
openNodes.pop_back();
|
|
closedNodes.insert(xp->guid());
|
|
+ openNodeMap.erase(xp);
|
|
|
|
// check if xp is the goal
|
|
if (xp == aDest) {
|
|
@@ -663,7 +655,12 @@
|
|
|
|
FGPositioned* yp = cache->loadById(other.second);
|
|
double edgeDistanceM = SGGeodesy::distanceM(xp->geod(), yp->geod());
|
|
- AStarOpenNodeRef y = findInOpen(openNodes, yp);
|
|
+ AStarOpenNodeRef y;
|
|
+ auto omit = openNodeMap.find(yp);
|
|
+ if (omit != openNodeMap.end()) {
|
|
+ y = omit->second;
|
|
+ }
|
|
if (y) { // already open
|
|
double g = x->distanceFromStart + edgeDistanceM;
|
|
if (g > y->distanceFromStart) {
|
|
@@ -683,6 +680,7 @@
|
|
} else { // not open, insert a new node for y into the heap
|
|
y = new AStarOpenNode(yp, edgeDistanceM, other.first, aDest, x);
|
|
openNodes.push_back(y);
|
|
+ openNodeMap[yp] = y;
|
|
std::push_heap(openNodes.begin(), openNodes.end(), ordering);
|
|
}
|
|
} // of neighbour iteration
|