@@ -721,8 +721,6 @@ class HierarchicalNSW : public AlgorithmInterface<dist_t> {
721
721
}
722
722
tableint internalId = search->second ;
723
723
lock_table.unlock ();
724
- // wait for element addition or update
725
- std::unique_lock <std::mutex> lock_el_update (link_list_update_locks_[(internalId & (max_update_element_locks - 1 ))]);
726
724
char * data_ptrv = getDataByInternalId (internalId);
727
725
size_t dim = *((size_t *) dist_func_param_);
728
726
std::vector<data_t > data;
@@ -746,8 +744,6 @@ class HierarchicalNSW : public AlgorithmInterface<dist_t> {
746
744
}
747
745
tableint internalId = search->second ;
748
746
lock_table.unlock ();
749
- // wait for element addition or update
750
- std::unique_lock <std::mutex> lock_el_update (link_list_update_locks_[(internalId & (max_update_element_locks - 1 ))]);
751
747
markDeletedInternal (internalId);
752
748
}
753
749
@@ -773,8 +769,11 @@ class HierarchicalNSW : public AlgorithmInterface<dist_t> {
773
769
774
770
775
771
/* *
776
- * Remove the deleted mark of the node, does NOT really change the current graph.
777
- */
772
+ * Remove the deleted mark of the node, does NOT really change the current graph.
773
+ *
774
+ * Note: the method is not safe to use when replacement of deleted elements is enabled
775
+ * bacause elements marked as deleted can be completely removed from the index
776
+ */
778
777
void unmarkDelete (labeltype label) {
779
778
std::unique_lock <std::mutex> lock_table (label_lookup_lock);
780
779
auto search = label_lookup_.find (label);
@@ -783,19 +782,14 @@ class HierarchicalNSW : public AlgorithmInterface<dist_t> {
783
782
}
784
783
tableint internalId = search->second ;
785
784
lock_table.unlock ();
786
- // wait for element addition or update
787
- std::unique_lock <std::mutex> lock_el_update (link_list_update_locks_[(internalId & (max_update_element_locks - 1 ))]);
788
785
unmarkDeletedInternal (internalId);
789
786
}
790
787
791
788
792
789
793
790
/* *
794
- * Remove the deleted mark of the node.
795
- *
796
- * Note: the method is not safe to use when replacement of deleted elements is enabled
797
- * bacause elements marked as deleted can be completely removed from the index
798
- */
791
+ * Remove the deleted mark of the node.
792
+ */
799
793
void unmarkDeletedInternal (tableint internalId) {
800
794
assert (internalId < cur_element_count);
801
795
if (isMarkedDeleted (internalId)) {
@@ -860,18 +854,16 @@ class HierarchicalNSW : public AlgorithmInterface<dist_t> {
860
854
addPoint (data_point, label);
861
855
return label;
862
856
} else {
863
- // wait for element addition or update
864
- std::unique_lock <std::mutex> lock_el_update (link_list_update_locks_[(internal_id_replaced & (max_update_element_locks - 1 ))]);
857
+ // no need to protect element from additions and updates as
858
+ // we assume that there are no concurrent operations on deleted element
865
859
labeltype label_replaced = getExternalLabel (internal_id_replaced);
866
860
setExternalLabel (internal_id_replaced, label);
867
- lock_el_update.unlock ();
868
861
869
862
std::unique_lock <std::mutex> lock_table (label_lookup_lock);
870
863
label_lookup_.erase (label_replaced);
871
864
label_lookup_[label] = internal_id_replaced;
872
865
lock_table.unlock ();
873
866
874
- lock_el_update.lock ();
875
867
unmarkDeletedInternal (internal_id_replaced);
876
868
updatePoint (data_point, internal_id_replaced, 1.0 );
877
869
0 commit comments