use crate::error::Result;
use std::collections::HashSet;
pub mod cpu;
pub use cpu::CpuBackend;
pub(crate) struct QueryResponse {
pub(crate) id: u32,
pub(crate) dist_sq: f32,
}
pub trait RingComputeBackend: Send + Sync {
fn name(&self) -> &'static str;
fn upload_f32_dataset(
&mut self,
dims: usize,
vectors: Vec<f32>,
norms_sq: Vec<f32>,
) -> Result<()>;
fn ring_query_f32(
&self,
dims: usize,
query: &[f32],
d_min: f32,
d_max: f32,
) -> Result<Vec<QueryResponse>>;
fn disk_query_f32(&self, dims: usize, query: &[f32], d_max: f32) -> Result<Vec<QueryResponse>> {
self.ring_query_f32(dims, query, 0.0, d_max)
}
fn disk_intersection_query_f32(
&self,
dims: usize,
disks: &[(&[f32], f32)],
) -> Result<Vec<QueryResponse>> {
let Some(&(first_query, first_d_max)) = disks.first() else {
return Ok(Vec::new());
};
let mut hits = self.disk_query_f32(dims, first_query, first_d_max)?;
for &(query, d_max) in &disks[1..] {
let ids: HashSet<u32> = self
.disk_query_f32(dims, query, d_max)?
.into_iter()
.map(|hit| hit.id)
.collect();
hits.retain(|hit| ids.contains(&hit.id));
}
Ok(hits)
}
}