split search_existing_point_on_level and regular search_on_level functions (#2167)

This commit is contained in:
Andrey Vasnetsov
2023-06-28 18:11:21 +02:00
committed by GitHub
parent 0784fd92c3
commit 247ea20a4e
3 changed files with 33 additions and 19 deletions

View File

@@ -98,7 +98,6 @@ pub trait GraphLayersBase {
level: usize,
ef: usize,
points_scorer: &mut FilteredScorer,
existing_links: &[PointOffsetType],
) -> FixedLengthPriorityQueue<ScoredPointOffset> {
let mut visited_list = self.get_visited_list_from_pool();
visited_list.check_and_update_visited(level_entry.idx);
@@ -106,15 +105,6 @@ pub trait GraphLayersBase {
self._search_on_level(&mut search_context, level, &mut visited_list, points_scorer);
for &existing_link in existing_links {
if !visited_list.check(existing_link) {
search_context.process_candidate(ScoredPointOffset {
idx: existing_link,
score: points_scorer.score_point(existing_link),
});
}
}
self.return_visited_list_to_pool(visited_list);
search_context.nearest
}
@@ -215,8 +205,7 @@ impl<TGraphLinks: GraphLinks> GraphLayers<TGraphLinks> {
&mut points_scorer,
);
let nearest =
self.search_on_level(zero_level_entry, 0, max(top, ef), &mut points_scorer, &[]);
let nearest = self.search_on_level(zero_level_entry, 0, max(top, ef), &mut points_scorer);
nearest.into_iter().take(top).collect_vec()
}
@@ -367,7 +356,6 @@ mod tests {
0,
32,
&mut scorer,
&[],
);
assert_eq!(nearest_on_level.len(), graph_links[0][0].len() + 1);

View File

@@ -13,6 +13,7 @@ use crate::index::hnsw_index::entry_points::EntryPoints;
use crate::index::hnsw_index::graph_layers::{GraphLayers, GraphLayersBase, LinkContainer};
use crate::index::hnsw_index::graph_links::GraphLinksConverter;
use crate::index::hnsw_index::point_scorer::FilteredScorer;
use crate::index::hnsw_index::search_context::SearchContext;
use crate::index::visited_pool::{VisitedList, VisitedPool};
use crate::spaces::tools::FixedLengthPriorityQueue;
use crate::types::{PointOffsetType, ScoreType};
@@ -282,6 +283,34 @@ impl GraphLayersBuilder {
result_list
}
fn search_existing_point_on_level(
&self,
level_entry: ScoredPointOffset,
level: usize,
ef: usize,
points_scorer: &mut FilteredScorer,
point_id: PointOffsetType,
) -> FixedLengthPriorityQueue<ScoredPointOffset> {
let mut visited_list = self.get_visited_list_from_pool();
visited_list.check_and_update_visited(level_entry.idx);
let mut search_context = SearchContext::new(level_entry, ef);
self._search_on_level(&mut search_context, level, &mut visited_list, points_scorer);
let existing_links = self.links_layers[point_id as usize][level].read();
for &existing_link in existing_links.iter() {
if !visited_list.check(existing_link) {
search_context.process_candidate(ScoredPointOffset {
idx: existing_link,
score: points_scorer.score_point(existing_link),
});
}
}
self.return_visited_list_to_pool(visited_list);
search_context.nearest
}
/// <https://github.com/nmslib/hnswlib/issues/99>
fn select_candidates_with_heuristic<F>(
candidates: FixedLengthPriorityQueue<ScoredPointOffset>,
@@ -339,14 +368,12 @@ impl GraphLayersBuilder {
let level_m = self.get_m(curr_level);
let nearest_points = {
let existing_links =
self.links_layers[point_id as usize][curr_level].read();
self.search_on_level(
self.search_existing_point_on_level(
level_entry,
curr_level,
self.ef_construct,
&mut points_scorer,
&existing_links,
point_id,
)
};

View File

@@ -34,8 +34,7 @@ fn search_in_builder(
&mut points_scorer,
);
let nearest =
builder.search_on_level(zero_level_entry, 0, max(top, ef), &mut points_scorer, &[]);
let nearest = builder.search_on_level(zero_level_entry, 0, max(top, ef), &mut points_scorer);
nearest.into_iter().take(top).collect_vec()
}