From 013def5142e515696e1f41b36c42486dfa4a1a38 Mon Sep 17 00:00:00 2001 From: Taras Tsugrii Date: Sun, 18 Jun 2023 20:49:26 -0500 Subject: [PATCH 1/2] [bruteforce] Fix bruteforce removePoint. --- hnswlib/bruteforce.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hnswlib/bruteforce.h b/hnswlib/bruteforce.h index 30b33ae9..15d10c98 100644 --- a/hnswlib/bruteforce.h +++ b/hnswlib/bruteforce.h @@ -84,10 +84,16 @@ class BruteforceSearch : public AlgorithmInterface { void removePoint(labeltype cur_external) { - size_t cur_c = dict_external_to_internal[cur_external]; + std::unique_lock lock(index_lock); - dict_external_to_internal.erase(cur_external); + auto found = dict_external_to_internal.find(cur_external); + if (found == dict_external_to_internal.end()) { + return; + } + + dict_external_to_internal.erase(found); + size_t cur_c = found->second; labeltype label = *((labeltype*)(data_ + size_per_element_ * (cur_element_count-1) + data_size_)); dict_external_to_internal[label] = cur_c; memcpy(data_ + size_per_element_ * cur_c, From 1ee95db9aa91a720f241b5aa147019e1e90acbff Mon Sep 17 00:00:00 2001 From: Taras Tsugrii Date: Sun, 18 Jun 2023 21:12:51 -0500 Subject: [PATCH 2/2] Use unique_ptr to manage visited_list_pool_. --- hnswlib/hnswalg.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/hnswlib/hnswalg.h b/hnswlib/hnswalg.h index 1356ce82..901b1878 100644 --- a/hnswlib/hnswalg.h +++ b/hnswlib/hnswalg.h @@ -8,6 +8,7 @@ #include #include #include +#include namespace hnswlib { typedef unsigned int tableint; @@ -33,7 +34,7 @@ class HierarchicalNSW : public AlgorithmInterface { double mult_{0.0}, revSize_{0.0}; int maxlevel_{0}; - VisitedListPool *visited_list_pool_{nullptr}; + std::unique_ptr visited_list_pool_{nullptr}; // Locks operations with element by label value mutable std::vector label_op_locks_; @@ -122,7 +123,7 @@ class HierarchicalNSW : public AlgorithmInterface { cur_element_count = 0; - visited_list_pool_ = new VisitedListPool(1, max_elements); + visited_list_pool_ = std::unique_ptr(new VisitedListPool(1, max_elements)); // initializations for special treatment of the first node enterpoint_node_ = -1; @@ -144,7 +145,6 @@ class HierarchicalNSW : public AlgorithmInterface { free(linkLists_[i]); } free(linkLists_); - delete visited_list_pool_; } @@ -573,8 +573,7 @@ class HierarchicalNSW : public AlgorithmInterface { if (new_max_elements < cur_element_count) throw std::runtime_error("Cannot resize, max element is less than the current number of elements"); - delete visited_list_pool_; - visited_list_pool_ = new VisitedListPool(1, new_max_elements); + visited_list_pool_.reset(new VisitedListPool(1, new_max_elements)); element_levels_.resize(new_max_elements); @@ -724,7 +723,7 @@ class HierarchicalNSW : public AlgorithmInterface { std::vector(max_elements).swap(link_list_locks_); std::vector(MAX_LABEL_OPERATION_LOCKS).swap(label_op_locks_); - visited_list_pool_ = new VisitedListPool(1, max_elements); + visited_list_pool_.reset(new VisitedListPool(1, max_elements)); linkLists_ = (char **) malloc(sizeof(void *) * max_elements); if (linkLists_ == nullptr)