|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use crate::core::{Id, Point}; |
|
|
|
|
|
|
|
|
pub type NearResult<T> = Result<T, NearError>; |
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq)] |
|
|
pub struct SearchResult { |
|
|
|
|
|
pub id: Id, |
|
|
|
|
|
|
|
|
|
|
|
pub score: f32, |
|
|
} |
|
|
|
|
|
impl SearchResult { |
|
|
pub fn new(id: Id, score: f32) -> Self { |
|
|
Self { id, score } |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq)] |
|
|
pub enum NearError { |
|
|
|
|
|
DimensionalityMismatch { expected: usize, got: usize }, |
|
|
|
|
|
|
|
|
IndexNotReady, |
|
|
|
|
|
|
|
|
IndexError(String), |
|
|
} |
|
|
|
|
|
impl std::fmt::Display for NearError { |
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
|
|
match self { |
|
|
NearError::DimensionalityMismatch { expected, got } => { |
|
|
write!(f, "Dimensionality mismatch: expected {}, got {}", expected, got) |
|
|
} |
|
|
NearError::IndexNotReady => write!(f, "Index not ready"), |
|
|
NearError::IndexError(msg) => write!(f, "Index error: {}", msg), |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
impl std::error::Error for NearError {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub trait Near: Send + Sync { |
|
|
|
|
|
|
|
|
|
|
|
fn near(&self, query: &Point, k: usize) -> NearResult<Vec<SearchResult>>; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn within(&self, query: &Point, threshold: f32) -> NearResult<Vec<SearchResult>>; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn add(&mut self, id: Id, point: &Point) -> NearResult<()>; |
|
|
|
|
|
|
|
|
fn remove(&mut self, id: Id) -> NearResult<()>; |
|
|
|
|
|
|
|
|
fn rebuild(&mut self) -> NearResult<()>; |
|
|
|
|
|
|
|
|
fn is_ready(&self) -> bool; |
|
|
|
|
|
|
|
|
fn len(&self) -> usize; |
|
|
|
|
|
|
|
|
fn is_empty(&self) -> bool { |
|
|
self.len() == 0 |
|
|
} |
|
|
} |
|
|
|