diff --git a/src/algorithm/hgraph/hgraph.cpp b/src/algorithm/hgraph/hgraph.cpp index ca37b3702..b3897c12c 100644 --- a/src/algorithm/hgraph/hgraph.cpp +++ b/src/algorithm/hgraph/hgraph.cpp @@ -134,6 +134,9 @@ HGraph::Tune(const std::string& parameters, bool disable_future_tuning) { } std::scoped_lock lock(this->add_mutex_); + if (this->immutable_.load(std::memory_order_acquire)) { + return false; + } // check which code need to tune and update create_param_ptr_ bool is_tune_base_code = false; @@ -433,14 +436,15 @@ HGraph::GetVectorByInnerId(InnerIdType inner_id, float* data) const { void HGraph::SetImmutable() { - if (this->immutable_) { + if (this->immutable_.load(std::memory_order_acquire)) { return; } + std::scoped_lock add_lock(this->add_mutex_); std::scoped_lock wlock(this->global_mutex_); this->neighbors_mutex_.reset(); this->neighbors_mutex_ = std::make_shared(); this->searcher_->SetMutexArray(this->neighbors_mutex_); - this->immutable_ = true; + this->immutable_.store(true, std::memory_order_release); } void diff --git a/src/algorithm/hgraph/hgraph_search.cpp b/src/algorithm/hgraph/hgraph_search.cpp index 9d23c374a..019a53d1a 100644 --- a/src/algorithm/hgraph/hgraph_search.cpp +++ b/src/algorithm/hgraph/hgraph_search.cpp @@ -82,10 +82,13 @@ HGraph::KnnSearch(const DatasetPtr& query, fmt::format("ef_search({}) must in range[1, {}]", params.ef_search, ef_search_threshold)); std::shared_lock force_remove_rlock; - if (this->support_force_remove()) { - force_remove_rlock = std::shared_lock(this->force_remove_mutex_); + std::shared_lock shared_lock; + if (!this->immutable_.load(std::memory_order_acquire)) { + if (this->support_force_remove()) { + force_remove_rlock = std::shared_lock(this->force_remove_mutex_); + } + shared_lock = std::shared_lock(this->global_mutex_); } - std::shared_lock shared_lock(this->global_mutex_); k = std::min(k, GetNumElements()); FilterPtr ft = this->create_search_filter(filter, params.use_extra_info_filter); @@ -357,10 +360,13 @@ HGraph::RangeSearch(const DatasetPtr& query, this->validate_range_args(query, radius, limited_size); std::shared_lock force_remove_rlock; - if (this->support_force_remove()) { - force_remove_rlock = std::shared_lock(this->force_remove_mutex_); + std::shared_lock shared_lock; + if (!this->immutable_.load(std::memory_order_acquire)) { + if (this->support_force_remove()) { + force_remove_rlock = std::shared_lock(this->force_remove_mutex_); + } + shared_lock = std::shared_lock(this->global_mutex_); } - std::shared_lock shared_lock(this->global_mutex_); InnerSearchParam search_param; search_param.ep = this->entry_point_id_; @@ -455,10 +461,13 @@ HGraph::SearchWithRequest(const SearchRequest& request) const { fmt::format("ef_search({}) must in range[1, {}]", params.ef_search, ef_search_threshold)); std::shared_lock force_remove_rlock; - if (this->support_force_remove()) { - force_remove_rlock = std::shared_lock(this->force_remove_mutex_); + std::shared_lock shared_lock; + if (!this->immutable_.load(std::memory_order_acquire)) { + if (this->support_force_remove()) { + force_remove_rlock = std::shared_lock(this->force_remove_mutex_); + } + shared_lock = std::shared_lock(this->global_mutex_); } - std::shared_lock shared_lock(this->global_mutex_); k = std::min(k, GetNumElements()); // Setup reasoning context if expected labels are provided. diff --git a/src/algorithm/inner_index_interface.h b/src/algorithm/inner_index_interface.h index 74901004f..a74783e45 100644 --- a/src/algorithm/inner_index_interface.h +++ b/src/algorithm/inner_index_interface.h @@ -567,7 +567,7 @@ class InnerIndexInterface { IndexFeatureListUPtr index_feature_list_{nullptr}; const InnerIndexParameterPtr create_param_ptr_{nullptr}; - bool immutable_{false}; + std::atomic immutable_{false}; protected: std::atomic current_memory_usage_{0}; diff --git a/src/algorithm/sindi/sindi.cpp b/src/algorithm/sindi/sindi.cpp index 32ff8f0de..e1dea85ad 100644 --- a/src/algorithm/sindi/sindi.cpp +++ b/src/algorithm/sindi/sindi.cpp @@ -709,7 +709,7 @@ SINDI::CalDistanceById(const DatasetPtr& query, void SINDI::SetImmutable() { std::scoped_lock wlock(this->global_mutex_); - this->immutable_ = true; + this->immutable_.store(true, std::memory_order_release); } void diff --git a/src/index/index_impl.h b/src/index/index_impl.h index 007623c94..4d270908b 100644 --- a/src/index/index_impl.h +++ b/src/index/index_impl.h @@ -58,7 +58,7 @@ class IndexImpl : public Index { return DatasetImpl::MakeEmptyDataset(); \ } #define CHECK_IMMUTABLE_INDEX(operation_str) \ - if (this->inner_index_->immutable_) { \ + if (this->inner_index_->immutable_.load(std::memory_order_acquire)) { \ return tl::unexpected(Error(ErrorType::UNSUPPORTED_INDEX_OPERATION, \ "immutable index no support " operation_str)); \ }