faster remove

This commit is contained in:
water
2024-03-31 12:21:54 -04:00
parent 7126394310
commit e16e01fdbc
2 changed files with 41 additions and 2 deletions
+36 -1
View File
@@ -13,7 +13,7 @@ class TrieMap {
private:
// TrieNode structure
struct TrieNode {
std::unordered_map<char, std::shared_ptr<TrieNode>> children;
std::map<char, std::shared_ptr<TrieNode>> children;
std::vector<std::shared_ptr<T>> elements;
};
@@ -72,6 +72,11 @@ class TrieMap {
// Remove the specified element from the TrieMap
void remove(const std::shared_ptr<T>& element) { remove_element(root, element); }
template <typename F>
int remove_matching(F&& f) {
return remove_matching_elements(root.get(), f);
}
// Return the total number of elements stored in the TrieMap
int size() const {
int count = 0;
@@ -104,6 +109,36 @@ class TrieMap {
}
}
/*!
* Remove elements where f(element) == true;
*/
template <typename F>
int remove_matching_elements(TrieNode* node, F&& f) {
int erase_count = 0;
// remove from this level
for (auto it = node->elements.begin(); it != node->elements.end();) {
if (f(it->get())) {
it = node->elements.erase(it);
erase_count++;
} else {
++it;
}
}
// remove children
for (auto it = node->children.begin(); it != node->children.end();) {
erase_count += remove_matching_elements(it->second.get(), f);
// remove child if it's empty
if (it->second->children.empty() && it->second->elements.empty()) {
it = node->children.erase(it);
} else {
++it;
}
}
return erase_count;
}
// Recursive function to remove the specified element from the TrieMap
bool remove_element(std::shared_ptr<TrieNode> node, const std::shared_ptr<T>& element) {
// Remove the element if it exists at this node
+5 -1
View File
@@ -311,9 +311,13 @@ std::vector<std::shared_ptr<SymbolInfo>> SymbolInfoMap::get_all_symbols() const
void SymbolInfoMap::evict_symbols_using_file_index(const std::string& file_path) {
const auto standardized_path = file_util::convert_to_unix_path_separators(file_path);
if (m_file_symbol_index.find(standardized_path) != m_file_symbol_index.end()) {
std::unordered_set<SymbolInfo*> sym_infos;
for (const auto& symbol : m_file_symbol_index.at(standardized_path)) {
m_symbol_map.remove(symbol);
sym_infos.insert(symbol.get());
}
m_symbol_map.remove_matching([&](SymbolInfo* info) { return sym_infos.count(info) != 0; });
m_file_symbol_index.erase(standardized_path);
}
}