java-topology/defects/flightgear-0003/patch/flightgear-0003.patch

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