1
0
Fork 0

GroundNetwork: improve ATC performance

Use an unordered-map to avoid a linear scan of all segments when
blocking segments during update()
This commit is contained in:
James Turner 2021-07-14 15:05:27 +01:00
parent 8c7ff0a486
commit 2915c5978f
2 changed files with 19 additions and 10 deletions

View file

@ -213,6 +213,9 @@ void FGGroundNetwork::init()
segment->oppositeDirection = opp;
opp->oppositeDirection = segment;
}
// establish node -> segment end cache
m_segmentsEndingAtNodeMap.insert(NodeFromSegmentMap::value_type{segment->getEnd(), segment});
}
networkInitialized = true;
@ -426,9 +429,8 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(FGTaxiNode* start, FGTaxiNode* en
void FGGroundNetwork::unblockAllSegments(time_t now)
{
FGTaxiSegmentVector::iterator tsi;
for ( tsi = segments.begin(); tsi != segments.end(); tsi++) {
(*tsi)->unblock(now);
for (auto& seg : segments) {
seg->unblock(now);
}
}
@ -437,13 +439,13 @@ void FGGroundNetwork::blockSegmentsEndingAt(FGTaxiSegment *seg, int blockId, tim
if (!seg)
throw sg_exception("Passed invalid segment");
const FGTaxiNode *node = seg->endNode;
FGTaxiSegmentVector::iterator tsi;
for ( tsi = segments.begin(); tsi != segments.end(); tsi++) {
FGTaxiSegment* otherSegment = *tsi;
if ((otherSegment->endNode == node) && (otherSegment != seg)) {
otherSegment->block(blockId, blockTime, now);
}
const auto range = m_segmentsEndingAtNodeMap.equal_range(seg->getEnd());
for (auto it = range.first; it != range.second; ++it) {
// our inbound segment will be included, so skip it
if (it->second == seg)
continue;
it->second->block(blockId, blockTime, now);
}
}

View file

@ -27,6 +27,7 @@
#include <simgear/compiler.h>
#include <string>
#include <unordered_map>
#include "gnnode.hxx"
#include "parking.hxx"
@ -224,6 +225,12 @@ private:
intVec freqGround; // </GROUND>
intVec freqTower; // </TOWER>
intVec freqApproach; // </APPROACH>
using NodeFromSegmentMap = std::unordered_multimap<FGTaxiNode*, FGTaxiSegment*>;
/// this map exists specifcially to make blockSegmentsEndingAt not be a bottleneck
NodeFromSegmentMap m_segmentsEndingAtNodeMap;
public:
FGGroundNetwork(FGAirport* pr);
~FGGroundNetwork();