1
0
Fork 0

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.
This commit is contained in:
jmt 2008-12-27 10:08:12 +00:00
parent cf42cfab16
commit b58c8b6f19

View file

@ -30,6 +30,7 @@
#include <iostream> #include <iostream>
#include <simgear/math/sg_geodesy.hxx> #include <simgear/math/sg_geodesy.hxx>
#include <simgear/timing/timestamp.hxx>
#include "positioned.hxx" #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 * A special purpose helper (imported by FGAirport::searchNamesAndIdents) to
* implement the AirportList dialog. It's unfortunate that it needs to reside * 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<char> &ct = std::use_facet<std::ctype<char> >(std::locale()); const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(std::locale());
std::string filter(aFilter); std::string filter(aFilter);
if (!filter.empty()) { bool hasFilter = !filter.empty();
if (hasFilter) {
ct.toupper((char *)filter.data(), (char *)filter.data() + filter.size()); ct.toupper((char *)filter.data(), (char *)filter.data() + filter.size());
} }
NamedPositionedIndex::const_iterator it = global_namedIndex.begin(); NamedPositionedIndex::const_iterator it = global_namedIndex.begin();
NamedPositionedIndex::const_iterator end = global_namedIndex.end(); NamedPositionedIndex::const_iterator end = global_namedIndex.end();
FGPositioned::List matches; // note this is a vector of raw pointers, not smart pointers, because it
if (aFilter.empty()) { // may get very large and smart-pointer-atomicity-locking then becomes a
matches.reserve(2000); // bottleneck for this case.
} std::vector<FGPositioned*> matches;
for (; it != end; ++it) { for (; it != end; ++it) {
FGPositioned::Type ty = it->second->type(); FGPositioned::Type ty = it->second->type();
@ -366,12 +377,8 @@ char** searchAirportNamesAndIdents(const std::string& aFilter)
continue; continue;
} }
if (aFilter.empty()) { if (hasFilter &&
matches.push_back(it->second); (it->second->name().find(aFilter) == std::string::npos) &&
continue;
}
if ((it->second->name().find(aFilter) == std::string::npos) &&
(it->second->ident().find(aFilter) == std::string::npos)) { (it->second->ident().find(aFilter) == std::string::npos)) {
continue; continue;
} }
@ -379,6 +386,9 @@ char** searchAirportNamesAndIdents(const std::string& aFilter)
matches.push_back(it->second); matches.push_back(it->second);
} }
// sort alphabetically on name
std::sort(matches.begin(), matches.end(), OrderByName());
// convert results to format comptible with puaList // convert results to format comptible with puaList
unsigned int numMatches = matches.size(); unsigned int numMatches = matches.size();
char** result = new char*[numMatches + 1]; char** result = new char*[numMatches + 1];