use crate::node::{NodeId, SearchHit};
use crate::VectorType;
use rayon::prelude::*;
pub fn search<T: VectorType>(
query: &[T],
flat_db_vectors: &[T],
dim: usize,
top_k: usize,
min_score: f32,
id_mapper: impl Fn(usize) -> NodeId + Sync,
) -> Vec<SearchHit> {
if flat_db_vectors.is_empty() || dim == 0 {
return Vec::new();
}
let mut hits: Vec<SearchHit> = flat_db_vectors
.par_chunks(dim)
.enumerate()
.filter_map(|(i, vec_slice)| {
let score = T::similarity(query, vec_slice);
if score >= min_score {
Some(SearchHit {
id: id_mapper(i),
score,
payload: serde_json::Value::Null,
})
} else {
None
}
})
.collect();
hits.sort_by(|a, b| b.score.partial_cmp(&a.score).unwrap_or(std::cmp::Ordering::Equal));
hits.truncate(top_k);
hits
}