Improve sorting a bit and fix some bugs in edge cases

makes nheko appear at the top, if you search for it as well as TWIM match the twim room
pull/547/head
Nicolas Werner 4 years ago
parent 28074794e7
commit 7d6bd67615
No known key found for this signature in database
GPG Key ID: C8D75E610773F2D9
  1. 5
      src/CompletionProxyModel.cpp
  2. 88
      src/CompletionProxyModel.h

@ -28,12 +28,15 @@ CompletionProxyModel::CompletionProxyModel(QAbstractItemModel *model,
->data(sourceModel()->index(i, 0), CompletionModel::SearchRole) ->data(sourceModel()->index(i, 0), CompletionModel::SearchRole)
.toString() .toString()
.toLower(); .toLower();
trie_.insert(string1.toUcs4(), i); if (!string1.isEmpty())
trie_.insert(string1.toUcs4(), i);
auto string2 = sourceModel() auto string2 = sourceModel()
->data(sourceModel()->index(i, 0), CompletionModel::SearchRole2) ->data(sourceModel()->index(i, 0), CompletionModel::SearchRole2)
.toString() .toString()
.toLower(); .toLower();
if (!string2.isEmpty())
trie_.insert(string2.toUcs4(), i);
} }
// insert the partial matches // insert the partial matches

@ -59,7 +59,7 @@ struct trie
std::vector<Value> search(const QVector<Key> &keys, //< TODO(Nico): replace this with a span std::vector<Value> search(const QVector<Key> &keys, //< TODO(Nico): replace this with a span
size_t result_count_limit, size_t result_count_limit,
size_t max_edit_distance = 2) const size_t max_edit_distance_ = 2) const
{ {
std::vector<Value> ret; std::vector<Value> ret;
if (!result_count_limit) if (!result_count_limit)
@ -79,52 +79,66 @@ struct trie
} }
}; };
if (auto e = this->next.find(keys[0]); e != this->next.end()) { auto limit = [&ret, result_count_limit] {
append( return std::min(result_count_limit, (result_count_limit - ret.size()) * 2);
e->second.search(keys.mid(1), result_count_limit, max_edit_distance)); };
}
if (max_edit_distance && ret.size() < result_count_limit) { // Try first exact matches, then with maximum errors
max_edit_distance -= 1; for (size_t max_edit_distance = 0;
max_edit_distance <= max_edit_distance_ && ret.size() < result_count_limit;
// swap chars case max_edit_distance += 1) {
if (keys.size() >= 2) { if (max_edit_distance && ret.size() < result_count_limit) {
auto t = this; max_edit_distance -= 1;
for (int i = 1; i >= 0; i--) {
if (auto e = t->next.find(keys[i]); e != t->next.end()) { // swap chars case
t = &e->second; if (keys.size() >= 2) {
} else { auto t = this;
t = nullptr; for (int i = 1; i >= 0; i--) {
break; if (auto e = t->next.find(keys[i]);
e != t->next.end()) {
t = &e->second;
} else {
t = nullptr;
break;
}
}
if (t) {
append(t->search(
keys.mid(2), limit(), max_edit_distance));
} }
} }
if (t) { // insert case
append(t->search(keys.mid(2), for (const auto &[k, t] : this->next) {
(result_count_limit - ret.size()) * 2, if (k == keys[0])
max_edit_distance)); continue;
if (ret.size() >= limit())
break;
// insert
append(t.search(keys, limit(), max_edit_distance));
} }
}
// delete character case // delete character case
append(this->search( append(this->search(keys.mid(1), limit(), max_edit_distance));
keys.mid(1), (result_count_limit - ret.size()) * 2, max_edit_distance));
// substitute and insert cases // substitute case
for (const auto &[k, t] : this->next) { for (const auto &[k, t] : this->next) {
if (k == keys[0] || ret.size() >= result_count_limit) if (k == keys[0])
break; continue;
if (ret.size() >= limit())
break;
// substitute // substitute
append(t.search( append(t.search(keys.mid(1), limit(), max_edit_distance));
keys.mid(1), result_count_limit - ret.size(), max_edit_distance)); }
if (ret.size() >= result_count_limit) max_edit_distance += 1;
break; }
// insert if (auto e = this->next.find(keys[0]); e != this->next.end()) {
append(t.search( append(e->second.search(keys.mid(1), limit(), max_edit_distance));
keys, result_count_limit - ret.size(), max_edit_distance));
} }
} }

Loading…
Cancel
Save