Use a heap instead of sorting to gather the best shell-candidates matches
O(n + k * log n) (with k = 100 here) instead of O(n log n), much faster with many candidates.
This commit is contained in:
parent
551263c564
commit
b6cab458ed
|
@ -904,11 +904,20 @@ void define_command(const ParametersParser& parser, Context& context, const Shel
|
||||||
if (RankedMatch match{candidate.first, candidate.second, query, query_letters})
|
if (RankedMatch match{candidate.first, candidate.second, query, query_letters})
|
||||||
matches.push_back(match);
|
matches.push_back(match);
|
||||||
}
|
}
|
||||||
std::sort(matches.begin(), matches.end());
|
|
||||||
matches.erase(std::unique(matches.begin(), matches.end()), matches.end());
|
constexpr size_t max_count = 100;
|
||||||
|
// Gather best max_count matches
|
||||||
|
auto greater = [](const RankedMatch& lhs,
|
||||||
|
const RankedMatch& rhs) { return rhs < lhs; };
|
||||||
|
auto first = matches.begin(), last = matches.end();
|
||||||
|
std::make_heap(first, last, greater);
|
||||||
CandidateList res;
|
CandidateList res;
|
||||||
for (auto& m : matches)
|
while(res.size() < max_count and first != last)
|
||||||
res.push_back(m.candidate().str());
|
{
|
||||||
|
if (res.empty() or res.back() != first->candidate())
|
||||||
|
res.push_back(first->candidate().str());
|
||||||
|
std::pop_heap(first, last--, greater);
|
||||||
|
}
|
||||||
|
|
||||||
return Completions{ 0_byte, pos_in_token, std::move(res) };
|
return Completions{ 0_byte, pos_in_token, std::move(res) };
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user