arms/ports/near.rs
1//! # Near Port
2//!
3//! Trait for finding related points.
4//!
5//! This is one of the five primitives of ARMS:
6//! `Near: fn(point, k) -> ids` - What's related?
7//!
8//! Implemented by index adapters (Flat, HNSW, etc.)
9
10use crate::core::{Id, Point};
11
12/// Result type for near operations
13pub type NearResult<T> = Result<T, NearError>;
14
15/// A search result with ID and distance/similarity score
16#[derive(Debug, Clone, PartialEq)]
17pub struct SearchResult {
18 /// The ID of the found point
19 pub id: Id,
20
21 /// Distance or similarity score
22 /// Interpretation depends on the proximity function used.
23 pub score: f32,
24}
25
26impl SearchResult {
27 pub fn new(id: Id, score: f32) -> Self {
28 Self { id, score }
29 }
30}
31
32/// Errors that can occur during near operations
33#[derive(Debug, Clone, PartialEq)]
34pub enum NearError {
35 /// The query point has wrong dimensionality
36 DimensionalityMismatch { expected: usize, got: usize },
37
38 /// Index is not built/ready
39 IndexNotReady,
40
41 /// Index backend error
42 IndexError(String),
43}
44
45impl std::fmt::Display for NearError {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 match self {
48 NearError::DimensionalityMismatch { expected, got } => {
49 write!(f, "Dimensionality mismatch: expected {}, got {}", expected, got)
50 }
51 NearError::IndexNotReady => write!(f, "Index not ready"),
52 NearError::IndexError(msg) => write!(f, "Index error: {}", msg),
53 }
54 }
55}
56
57impl std::error::Error for NearError {}
58
59/// Trait for finding related points
60///
61/// Index adapters implement this trait.
62pub trait Near: Send + Sync {
63 /// Find k nearest points to query
64 ///
65 /// Returns results sorted by relevance (most relevant first).
66 fn near(&self, query: &Point, k: usize) -> NearResult<Vec<SearchResult>>;
67
68 /// Find all points within a distance/similarity threshold
69 ///
70 /// For distance metrics (Euclidean), finds points with distance < threshold.
71 /// For similarity metrics (Cosine), finds points with similarity > threshold.
72 fn within(&self, query: &Point, threshold: f32) -> NearResult<Vec<SearchResult>>;
73
74 /// Add a point to the index
75 ///
76 /// Call this after placing a point in storage.
77 fn add(&mut self, id: Id, point: &Point) -> NearResult<()>;
78
79 /// Remove a point from the index
80 fn remove(&mut self, id: Id) -> NearResult<()>;
81
82 /// Rebuild the index (if needed for performance)
83 fn rebuild(&mut self) -> NearResult<()>;
84
85 /// Check if the index is ready for queries
86 fn is_ready(&self) -> bool;
87
88 /// Get the number of indexed points
89 fn len(&self) -> usize;
90
91 /// Check if the index is empty
92 fn is_empty(&self) -> bool {
93 self.len() == 0
94 }
95}