@@ -103,7 +103,7 @@ class HNSWIndex : public VecSimIndexAbstract<DistType>,
103103 mutable VisitedNodesHandlerPool visited_nodes_handler_pool;
104104 mutable std::mutex entry_point_guard_;
105105 mutable std::mutex index_data_guard_;
106- mutable vecsim_stl::vector<std::mutex > element_neighbors_locks_;
106+ mutable vecsim_stl::vector<vecsim_stl::one_byte_mutex > element_neighbors_locks_;
107107
108108#ifdef BUILD_TESTS
109109#include " VecSim/algorithms/hnsw/hnsw_base_tests_friends.h"
@@ -159,11 +159,10 @@ class HNSWIndex : public VecSimIndexAbstract<DistType>,
159159 const std::pair<DistType, idType> &neighbor_data,
160160 idType *new_node_neighbors_list,
161161 idType *neighbor_neighbors_list,
162- std::unique_lock<std::mutex> &node_lock,
163- std::unique_lock<std::mutex> &neighbor_lock);
164- inline idType mutuallyConnectNewElement (idType new_node_id,
165- candidatesMaxHeap<DistType> &top_candidates,
166- size_t level);
162+ std::unique_lock<vecsim_stl::one_byte_mutex> &node_lock,
163+ std::unique_lock<vecsim_stl::one_byte_mutex> &neighbor_lock);
164+ idType mutuallyConnectNewElement (idType new_node_id,
165+ candidatesMaxHeap<DistType> &top_candidates, size_t level);
167166 template <bool with_timeout>
168167 void greedySearchLevel (const void *vector_data, size_t level, idType &curObj, DistType &curDist,
169168 void *timeoutCtx = nullptr , VecSimQueryResult_Code *rc = nullptr ) const ;
@@ -521,7 +520,7 @@ DistType HNSWIndex<DataType, DistType>::processCandidate(
521520 tag_t *elements_tags, vecsim_stl::abstract_priority_queue<DistType, Identifier> &top_candidates,
522521 candidatesMaxHeap<DistType> &candidate_set, DistType lowerBound) const {
523522
524- std::unique_lock<std::mutex > lock (element_neighbors_locks_[curNodeId]);
523+ std::unique_lock<vecsim_stl::one_byte_mutex > lock (element_neighbors_locks_[curNodeId]);
525524 idType *node_links = get_linklist_at_level (curNodeId, layer);
526525 linkListSize links_num = getListCount (node_links);
527526
@@ -573,7 +572,7 @@ void HNSWIndex<DataType, DistType>::processCandidate_RangeSearch(
573572 tag_t *elements_tags, std::unique_ptr<vecsim_stl::abstract_results_container> &results,
574573 candidatesMaxHeap<DistType> &candidate_set, DistType dyn_range, double radius) const {
575574
576- std::unique_lock<std::mutex > lock (element_neighbors_locks_[curNodeId]);
575+ std::unique_lock<vecsim_stl::one_byte_mutex > lock (element_neighbors_locks_[curNodeId]);
577576 idType *node_links = get_linklist_at_level (curNodeId, layer);
578577 linkListSize links_num = getListCount (node_links);
579578
@@ -703,7 +702,7 @@ template <typename DataType, typename DistType>
703702void HNSWIndex<DataType, DistType>::revisitNeighborConnections(
704703 size_t level, idType new_node_id, const std::pair<DistType, idType> &neighbor_data,
705704 idType *new_node_neighbors_list, idType *neighbor_neighbors_list,
706- std::unique_lock<std::mutex > &node_lock, std::unique_lock<std::mutex > &neighbor_lock) {
705+ std::unique_lock<vecsim_stl::one_byte_mutex > &node_lock, std::unique_lock<vecsim_stl::one_byte_mutex > &neighbor_lock) {
707706 // Note - expect that node_lock and neighbor_lock are locked at that point.
708707
709708 // Collect the existing neighbors and the new node as the neighbor's neighbors candidates.
@@ -760,9 +759,10 @@ void HNSWIndex<DataType, DistType>::revisitNeighborConnections(
760759
761760 std::sort (nodes_to_update.begin (), nodes_to_update.end ());
762761 size_t nodes_to_update_count = nodes_to_update.size ();
763- std::unique_lock<std::mutex > locks[nodes_to_update_count];
762+ std::unique_lock<vecsim_stl::one_byte_mutex > locks[nodes_to_update_count];
764763 for (size_t i = 0 ; i < nodes_to_update_count; i++) {
765- locks[i] = std::unique_lock<std::mutex>(element_neighbors_locks_[nodes_to_update[i]]);
764+ locks[i] = std::unique_lock<vecsim_stl::one_byte_mutex>(
765+ element_neighbors_locks_[nodes_to_update[i]]);
766766 }
767767
768768 auto *neighbour_incoming_edges = getIncomingEdgesPtr (selected_neighbor, level);
@@ -855,17 +855,19 @@ idType HNSWIndex<DataType, DistType>::mutuallyConnectNewElement(
855855
856856 for (auto &neighbor_data : selected_neighbors) {
857857 idType selected_neighbor = neighbor_data.second ; // neighbor's id
858- std::unique_lock<std::mutex > node_lock;
859- std::unique_lock<std::mutex > neighbor_lock;
858+ std::unique_lock<vecsim_stl::one_byte_mutex > node_lock;
859+ std::unique_lock<vecsim_stl::one_byte_mutex > neighbor_lock;
860860 idType lower_id = (new_node_id < selected_neighbor) ? new_node_id : selected_neighbor;
861861 if (lower_id == new_node_id) {
862- node_lock = std::unique_lock<std::mutex>(element_neighbors_locks_[new_node_id]);
863- neighbor_lock =
864- std::unique_lock<std::mutex>(element_neighbors_locks_[selected_neighbor]);
862+ node_lock =
863+ std::unique_lock<vecsim_stl::one_byte_mutex>(element_neighbors_locks_[new_node_id]);
864+ neighbor_lock = std::unique_lock<vecsim_stl::one_byte_mutex>(
865+ element_neighbors_locks_[selected_neighbor]);
865866 } else {
866- neighbor_lock =
867- std::unique_lock<std::mutex>(element_neighbors_locks_[selected_neighbor]);
868- node_lock = std::unique_lock<std::mutex>(element_neighbors_locks_[new_node_id]);
867+ neighbor_lock = std::unique_lock<vecsim_stl::one_byte_mutex>(
868+ element_neighbors_locks_[selected_neighbor]);
869+ node_lock =
870+ std::unique_lock<vecsim_stl::one_byte_mutex>(element_neighbors_locks_[new_node_id]);
869871 }
870872
871873 // get the updated count - this may change between iterations due to releasing the lock.
@@ -1124,7 +1126,7 @@ void HNSWIndex<DataType, DistType>::greedySearchLevel(const void *vector_data, s
11241126 return ;
11251127 }
11261128 changed = false ;
1127- std::unique_lock<std::mutex > lock (element_neighbors_locks_[curObj]);
1129+ std::unique_lock<vecsim_stl::one_byte_mutex > lock (element_neighbors_locks_[curObj]);
11281130 idType *node_links = get_linklist (curObj, level);
11291131 linkListSize links_count = getListCount (node_links);
11301132
@@ -1150,7 +1152,7 @@ void HNSWIndex<DataType, DistType>::resizeIndexInternal(size_t new_max_elements)
11501152 element_levels_.shrink_to_fit ();
11511153 resizeLabelLookup (new_max_elements);
11521154 visited_nodes_handler_pool.resize (new_max_elements);
1153- vecsim_stl::vector<std::mutex >(new_max_elements, this ->allocator )
1155+ vecsim_stl::vector<vecsim_stl::one_byte_mutex >(new_max_elements, this ->allocator )
11541156 .swap (element_neighbors_locks_);
11551157 // Reallocate base layer
11561158 char *data_level0_memory_new = (char *)this ->allocator ->reallocate (
0 commit comments