From e2170b918a2c56bbbe04a9e5d78ceaea6fbe2715 Mon Sep 17 00:00:00 2001 From: Jalin Wang Date: Thu, 30 Jul 2026 11:40:07 +0800 Subject: [PATCH] Fix heap invariants in group search --- src/core/algorithm/diskann/diskann_indexer.cc | 6 +++--- src/core/algorithm/hnsw/hnsw_algorithm.cc | 6 +++--- src/core/algorithm/hnsw/hnsw_streamer.cc | 6 +++--- .../algorithm/hnsw_rabitq/hnsw_rabitq_query_algorithm.cc | 6 +++--- src/core/algorithm/hnsw_rabitq/hnsw_rabitq_streamer.cc | 4 ++-- src/core/algorithm/hnsw_sparse/hnsw_sparse_algorithm.cc | 8 ++++---- src/core/algorithm/hnsw_sparse/hnsw_sparse_searcher.cc | 4 ++-- src/core/algorithm/hnsw_sparse/hnsw_sparse_streamer.cc | 4 ++-- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/core/algorithm/diskann/diskann_indexer.cc b/src/core/algorithm/diskann/diskann_indexer.cc index 32e7ff67c..66df5f2ae 100644 --- a/src/core/algorithm/diskann/diskann_indexer.cc +++ b/src/core/algorithm/diskann/diskann_indexer.cc @@ -982,7 +982,7 @@ int DiskAnnIndexer::cached_beam_search_by_group(DiskAnnContext *ctx) { group_topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace(id, info); + group_topk_heap.emplace(id, info); } // stage 2, expand to reach group num as possible @@ -1106,7 +1106,7 @@ int DiskAnnIndexer::cached_beam_search_by_group(DiskAnnContext *ctx) { group_topk_heap.limit(ctx->group_topk()); } - group_topk_heap.emplace_back( + group_topk_heap.emplace( std::get<0>(cached_neighbor), VectorInfo(cur_expanded_dist, make_vector_copy(node_fp_coords_copy))); @@ -1160,7 +1160,7 @@ int DiskAnnIndexer::cached_beam_search_by_group(DiskAnnContext *ctx) { group_topk_heap.limit(ctx->group_topk()); } - group_topk_heap.emplace_back( + group_topk_heap.emplace( frontier_neighbor.first, VectorInfo(cur_expanded_dist, make_vector_copy(data_buf))); diff --git a/src/core/algorithm/hnsw/hnsw_algorithm.cc b/src/core/algorithm/hnsw/hnsw_algorithm.cc index 1fd6f6567..902ce0aa7 100644 --- a/src/core/algorithm/hnsw/hnsw_algorithm.cc +++ b/src/core/algorithm/hnsw/hnsw_algorithm.cc @@ -468,7 +468,7 @@ void HnswAlgorithm::expand_neighbors_by_group( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(id, score); + topk_heap.emplace(id, score); } // stage 2, expand to reach group num as possible @@ -492,7 +492,7 @@ void HnswAlgorithm::expand_neighbors_by_group( float score = topk[i].second; visit.set_visited(id); - candidates.emplace_back(id, score); + candidates.emplace(id, score); } // do expand @@ -551,7 +551,7 @@ void HnswAlgorithm::expand_neighbors_by_group( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(node, cur_dist); + topk_heap.emplace(node, cur_dist); if (group_topk_heaps.size() >= ctx->group_num()) { break; diff --git a/src/core/algorithm/hnsw/hnsw_streamer.cc b/src/core/algorithm/hnsw/hnsw_streamer.cc index 8bd03f276..7c4c58768 100644 --- a/src/core/algorithm/hnsw/hnsw_streamer.cc +++ b/src/core/algorithm/hnsw/hnsw_streamer.cc @@ -792,7 +792,7 @@ int HnswStreamer::search_bf_impl( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(id, dist); + topk_heap.emplace(id, dist); } } ctx->topk_to_result(q); @@ -884,7 +884,7 @@ int HnswStreamer::search_bf_by_p_keys_impl( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(id, dist); + topk_heap.emplace(id, dist); } } } @@ -924,4 +924,4 @@ int HnswStreamer::search_bf_by_p_keys_impl( INDEX_FACTORY_REGISTER_STREAMER(HnswStreamer); } // namespace core -} // namespace zvec \ No newline at end of file +} // namespace zvec diff --git a/src/core/algorithm/hnsw_rabitq/hnsw_rabitq_query_algorithm.cc b/src/core/algorithm/hnsw_rabitq/hnsw_rabitq_query_algorithm.cc index d15cf111b..04177064a 100644 --- a/src/core/algorithm/hnsw_rabitq/hnsw_rabitq_query_algorithm.cc +++ b/src/core/algorithm/hnsw_rabitq/hnsw_rabitq_query_algorithm.cc @@ -224,7 +224,7 @@ void HnswRabitqQueryAlgorithm::expand_neighbors_by_group( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(id, score); + topk_heap.emplace(id, score); } // stage 2, expand to reach group num as possible @@ -245,7 +245,7 @@ void HnswRabitqQueryAlgorithm::expand_neighbors_by_group( auto score = topk[i].second; visit.set_visited(id); - candidates.emplace_back(id, score); + candidates.emplace(id, score); } // do expand @@ -291,7 +291,7 @@ void HnswRabitqQueryAlgorithm::expand_neighbors_by_group( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(node, ResultRecord(candest)); + topk_heap.emplace(node, ResultRecord(candest)); if (group_topk_heaps.size() >= ctx->group_num()) { break; diff --git a/src/core/algorithm/hnsw_rabitq/hnsw_rabitq_streamer.cc b/src/core/algorithm/hnsw_rabitq/hnsw_rabitq_streamer.cc index 6ebf57f20..253e6c2ee 100644 --- a/src/core/algorithm/hnsw_rabitq/hnsw_rabitq_streamer.cc +++ b/src/core/algorithm/hnsw_rabitq/hnsw_rabitq_streamer.cc @@ -848,7 +848,7 @@ int HnswRabitqStreamer::search_bf_impl( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(id, dist); + topk_heap.emplace(id, dist); } } ctx->topk_to_result(q); @@ -950,7 +950,7 @@ int HnswRabitqStreamer::search_bf_by_p_keys_impl( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(id, dist); + topk_heap.emplace(id, dist); } } } diff --git a/src/core/algorithm/hnsw_sparse/hnsw_sparse_algorithm.cc b/src/core/algorithm/hnsw_sparse/hnsw_sparse_algorithm.cc index 7538dfc8b..5c8adfb84 100644 --- a/src/core/algorithm/hnsw_sparse/hnsw_sparse_algorithm.cc +++ b/src/core/algorithm/hnsw_sparse/hnsw_sparse_algorithm.cc @@ -303,7 +303,7 @@ void HnswSparseAlgorithm::expand_neighbors_by_group( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(id, score); + topk_heap.emplace(id, score); } // stage 2, expand to reach group num as possible @@ -325,7 +325,7 @@ void HnswSparseAlgorithm::expand_neighbors_by_group( float score = topk[i].second; visit.set_visited(id); - candidates.emplace_back(id, score); + candidates.emplace(id, score); } // do expand @@ -382,7 +382,7 @@ void HnswSparseAlgorithm::expand_neighbors_by_group( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(node, cur_dist); + topk_heap.emplace(node, cur_dist); if (group_topk_heaps.size() >= ctx->group_num()) { break; @@ -521,4 +521,4 @@ void HnswSparseAlgorithm::reverse_update_neighbors(HnswSparseDistCalculator &dc, } } // namespace core -} // namespace zvec \ No newline at end of file +} // namespace zvec diff --git a/src/core/algorithm/hnsw_sparse/hnsw_sparse_searcher.cc b/src/core/algorithm/hnsw_sparse/hnsw_sparse_searcher.cc index 51cbacb4b..2a41a80f4 100644 --- a/src/core/algorithm/hnsw_sparse/hnsw_sparse_searcher.cc +++ b/src/core/algorithm/hnsw_sparse/hnsw_sparse_searcher.cc @@ -348,7 +348,7 @@ int HnswSparseSearcher::search_bf_impl( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(id, dist); + topk_heap.emplace(id, dist); } } ctx->topk_to_result(q); @@ -459,7 +459,7 @@ int HnswSparseSearcher::search_bf_by_p_keys_impl( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(id, dist); + topk_heap.emplace(id, dist); } } } diff --git a/src/core/algorithm/hnsw_sparse/hnsw_sparse_streamer.cc b/src/core/algorithm/hnsw_sparse/hnsw_sparse_streamer.cc index 20c215257..9638d36d1 100644 --- a/src/core/algorithm/hnsw_sparse/hnsw_sparse_streamer.cc +++ b/src/core/algorithm/hnsw_sparse/hnsw_sparse_streamer.cc @@ -766,7 +766,7 @@ int HnswSparseStreamer::search_bf_impl( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(id, dist); + topk_heap.emplace(id, dist); } } ctx->topk_to_result(q); @@ -889,7 +889,7 @@ int HnswSparseStreamer::search_bf_by_p_keys_impl( if (topk_heap.empty()) { topk_heap.limit(ctx->group_topk()); } - topk_heap.emplace_back(id, dist); + topk_heap.emplace(id, dist); } } }