use glam::Vec3;
#[derive(Debug, Clone, Copy)]
pub enum DistanceMetric {
Euclidean,
Manhattan,
Chebyshev,
}
#[derive(Debug, Clone, Copy)]
pub enum BitsetOp {
And,
Or,
Xor,
}
pub trait ComputeBackend: Send + Sync {
fn distance(&self, a: &Vec3, b: &Vec3, metric: DistanceMetric) -> f32;
fn distance_batch(&self, points: &[Vec3], query: &Vec3, metric: DistanceMetric) -> Vec<f32>;
fn bitset_op(&self, a: &[u64], b: &[u64], op: BitsetOp) -> Vec<u64>;
}
pub struct CpuBackend;
impl ComputeBackend for CpuBackend {
fn distance(&self, a: &Vec3, b: &Vec3, _metric: DistanceMetric) -> f32 {
(*a - *b).length()
}
fn distance_batch(&self, points: &[Vec3], query: &Vec3, _metric: DistanceMetric) -> Vec<f32> {
points.iter().map(|p| (*p - *query).length()).collect()
}
fn bitset_op(&self, a: &[u64], b: &[u64], op: BitsetOp) -> Vec<u64> {
match op {
BitsetOp::And => a.iter().zip(b.iter()).map(|(x, y)| x & y).collect(),
BitsetOp::Or => a.iter().zip(b.iter()).map(|(x, y)| x | y).collect(),
BitsetOp::Xor => a.iter().zip(b.iter()).map(|(x, y)| x ^ y).collect(),
}
}
}