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:
parent
cf42cfab16
commit
b58c8b6f19
1 changed files with 21 additions and 11 deletions
|
@ -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];
|
||||||
|
|
Loading…
Reference in a new issue