Compare commits

..

3 Commits

Author SHA1 Message Date
monxa a4381eb040
Merge 4f7996b1ea into 760af804c0 2024-10-01 01:44:38 +02:00
Alexander Montag 4f7996b1ea
Fix new filtering approach for TreeSearch 2024-10-01 01:44:16 +02:00
Alexander Montag 74cf9855a7
Fix tree filtering with new approach 2024-10-01 00:13:08 +02:00
1 changed files with 37 additions and 16 deletions

View File

@ -56,34 +56,55 @@ void TreeSearch::_clean_callable_cache() {
} }
void TreeSearch::_filter_tree(const String &p_search_mask) { void TreeSearch::_filter_tree(const String &p_search_mask) {
if (matching_entries.size() == 0) { if (matching_entries.is_empty()) {
return; return;
} }
Vector<bool> item_visibilities;
item_visibilities.resize(ordered_tree_items.size());
item_visibilities.fill(false);
// Make all entries visible that have any matching descendents. O(n)
for (int i = 0; i < ordered_tree_items.size(); i++) { for (int i = 0; i < ordered_tree_items.size(); i++) {
TreeItem *cur_item = ordered_tree_items[i]; TreeItem *entry = ordered_tree_items[i];
if (number_matches.has(entry) && number_matches[entry] > 0) {
if (number_matches.has(cur_item)) { item_visibilities.set(i, true);
continue;
} }
}
TreeItem *first_counting_ancestor = cur_item; // Make all descendents of matching entries visible. O(n) * log(|matching_entries|)
bool parents_visible = true; for (int i = 0; i < ordered_tree_items.size(); i++) {
while (first_counting_ancestor && !number_matches.has(first_counting_ancestor)) { TreeItem *entry = ordered_tree_items[i];
// Performance: we only need to check the first visible ancestor. This is already optimal because of the ordering in ordered_tree_items. if (_vector_has_bsearch(matching_entries, entry)) {
if (!first_counting_ancestor->is_visible()){ // the [next_entry] at the same depth or depth above.
parents_visible = false; TreeItem *next_entry = entry->get_next();
break;
// search above current depth if no [next_entry].
while (!next_entry && entry) {
entry = entry->get_parent();
} }
first_counting_ancestor = first_counting_ancestor->get_parent(); if (entry) {
next_entry = entry->get_next();
}
// mark visible all successors upto next entry at the same depth or above
int j = i;
for (; j < ordered_tree_items.size() && ordered_tree_items[j] != next_entry; j++) {
item_visibilities.set(j, true);
}
i = j - 1; // every entry is only processed once.
} }
if (!parents_visible || !first_counting_ancestor || !_vector_has_bsearch(matching_entries, first_counting_ancestor)) { }
cur_item->set_visible(false);
// Apply visibility. O(n)
for (int i = 0; i < ordered_tree_items.size(); i++) {
if (!item_visibilities[i]) {
ordered_tree_items[i]->set_visible(false);
} }
} }
} }
// makes all tree items visible. // Makes all tree items visible.
void TreeSearch::_clear_filter() { void TreeSearch::_clear_filter() {
ERR_FAIL_COND(!tree_reference); ERR_FAIL_COND(!tree_reference);
Vector<TreeItem *> items = { tree_reference->get_root() }; Vector<TreeItem *> items = { tree_reference->get_root() };