From b58c8b6f19fdbf13fcb0315dff7ad5d4c99c2110 Mon Sep 17 00:00:00 2001 From: jmt Date: Sat, 27 Dec 2008 10:08:12 +0000 Subject: [PATCH] Further work (still not enabled) on a fast + correct implementation of the airportList search function. At least for me (with a mutex-based SGAtomic), large vectors of referenced-pointers is a Bad Thing - copying on vector resize is thrashing the locks. --- src/Navaids/positioned.cxx | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Navaids/positioned.cxx b/src/Navaids/positioned.cxx index 374450739..a705c8495 100644 --- a/src/Navaids/positioned.cxx +++ b/src/Navaids/positioned.cxx @@ -30,6 +30,7 @@ #include #include +#include #include "positioned.hxx" @@ -339,6 +340,15 @@ spatialGetClosest(const SGGeod& aPos, unsigned int aN, double aCutoffNm, FGPosit ////////////////////////////////////////////////////////////////////////////// +class OrderByName +{ +public: + bool operator()(FGPositioned* a, FGPositioned* b) const + { + return a->name() < b->name(); + } +}; + /** * A special purpose helper (imported by FGAirport::searchNamesAndIdents) to * implement the AirportList dialog. It's unfortunate that it needs to reside @@ -348,17 +358,18 @@ char** searchAirportNamesAndIdents(const std::string& aFilter) { const std::ctype &ct = std::use_facet >(std::locale()); std::string filter(aFilter); - if (!filter.empty()) { + bool hasFilter = !filter.empty(); + if (hasFilter) { ct.toupper((char *)filter.data(), (char *)filter.data() + filter.size()); } NamedPositionedIndex::const_iterator it = global_namedIndex.begin(); NamedPositionedIndex::const_iterator end = global_namedIndex.end(); - FGPositioned::List matches; - if (aFilter.empty()) { - matches.reserve(2000); - } + // note this is a vector of raw pointers, not smart pointers, because it + // may get very large and smart-pointer-atomicity-locking then becomes a + // bottleneck for this case. + std::vector matches; for (; it != end; ++it) { FGPositioned::Type ty = it->second->type(); @@ -366,12 +377,8 @@ char** searchAirportNamesAndIdents(const std::string& aFilter) continue; } - if (aFilter.empty()) { - matches.push_back(it->second); - continue; - } - - if ((it->second->name().find(aFilter) == std::string::npos) && + if (hasFilter && + (it->second->name().find(aFilter) == std::string::npos) && (it->second->ident().find(aFilter) == std::string::npos)) { continue; } @@ -379,6 +386,9 @@ char** searchAirportNamesAndIdents(const std::string& aFilter) matches.push_back(it->second); } + // sort alphabetically on name + std::sort(matches.begin(), matches.end(), OrderByName()); + // convert results to format comptible with puaList unsigned int numMatches = matches.size(); char** result = new char*[numMatches + 1];