use std::collections::HashSet;
use crate::distance::DistanceMetric;
use super::delta::DeltaBuffer;
#[must_use]
pub fn merge_with_delta(
hnsw_results: Vec<(u64, f32)>,
delta: &DeltaBuffer,
query: &[f32],
k: usize,
metric: DistanceMetric,
) -> Vec<(u64, f32)> {
if !delta.is_searchable() {
return hnsw_results;
}
let delta_results = delta.search(query, k, metric);
if delta_results.is_empty() {
return hnsw_results;
}
let delta_ids: HashSet<u64> = delta_results.iter().map(|(id, _)| *id).collect();
let mut merged: Vec<(u64, f32)> = hnsw_results
.into_iter()
.filter(|(id, _)| !delta_ids.contains(id))
.collect();
merged.extend(delta_results);
metric.sort_results(&mut merged);
merged.truncate(k);
merged
}
#[must_use]
pub fn merge_with_delta_scored(
hnsw_results: Vec<crate::scored_result::ScoredResult>,
delta: &DeltaBuffer,
query: &[f32],
k: usize,
metric: DistanceMetric,
) -> Vec<crate::scored_result::ScoredResult> {
if !delta.is_searchable() {
return hnsw_results;
}
let delta_results = delta.search(query, k, metric);
if delta_results.is_empty() {
return hnsw_results;
}
let delta_ids: HashSet<u64> = delta_results.iter().map(|(id, _)| *id).collect();
let mut merged: Vec<(u64, f32)> = hnsw_results
.into_iter()
.filter(|sr| !delta_ids.contains(&sr.id))
.map(Into::into)
.collect();
merged.extend(delta_results);
metric.sort_results(&mut merged);
merged.truncate(k);
merged
.into_iter()
.map(crate::scored_result::ScoredResult::from)
.collect()
}