pub trait VectorIndex: Send + Sync {
// Required methods
fn insert(&self, id: usize, embedding: &[f32]) -> Result<()>;
fn insert_batch(&self, items: &[(&Vec<f32>, usize)]) -> Result<()>;
fn search(
&self,
query: &[f32],
k: usize,
ef_search: usize,
) -> Result<Vec<(usize, f32)>>;
fn search_filtered(
&self,
query: &[f32],
k: usize,
ef_search: usize,
filter: &(dyn Fn(&usize) -> bool + Sync),
) -> Result<Vec<(usize, f32)>>;
fn delete(&self, id: usize) -> Result<()>;
fn is_deleted(&self, id: usize) -> bool;
fn len(&self) -> usize;
fn save(&self, dir: &Path, name: &str) -> Result<()>;
// Provided method
fn is_empty(&self) -> bool { ... }
}Expand description
Vector index trait for approximate nearest neighbor search.
Implementations must be Send + Sync for use inside PulseDB.
IDs are usize to align with hnsw_rs’s DataId type.
All mutating methods (insert, delete) take &self and use
interior mutability. This enables concurrent reads during search
while writes are serialized internally.
Required Methods§
Sourcefn insert(&self, id: usize, embedding: &[f32]) -> Result<()>
fn insert(&self, id: usize, embedding: &[f32]) -> Result<()>
Inserts a single vector with the given ID.
Sourcefn insert_batch(&self, items: &[(&Vec<f32>, usize)]) -> Result<()>
fn insert_batch(&self, items: &[(&Vec<f32>, usize)]) -> Result<()>
Inserts a batch of vectors.
More efficient than individual inserts for large batches due to reduced locking overhead and parallel insertion.
Sourcefn search(
&self,
query: &[f32],
k: usize,
ef_search: usize,
) -> Result<Vec<(usize, f32)>>
fn search( &self, query: &[f32], k: usize, ef_search: usize, ) -> Result<Vec<(usize, f32)>>
Searches for the k nearest neighbors to the query vector.
Returns (id, distance) pairs sorted by distance ascending
(closest first). Distance metric is cosine distance:
0.0 = identical, 2.0 = opposite.
Sourcefn search_filtered(
&self,
query: &[f32],
k: usize,
ef_search: usize,
filter: &(dyn Fn(&usize) -> bool + Sync),
) -> Result<Vec<(usize, f32)>>
fn search_filtered( &self, query: &[f32], k: usize, ef_search: usize, filter: &(dyn Fn(&usize) -> bool + Sync), ) -> Result<Vec<(usize, f32)>>
Searches with a filter predicate applied during traversal.
Only points where filter(id) returns true are considered.
This is filter-during-traversal, NOT post-filtering — critical
for maintaining result count when many points are filtered.
The filter must implement hnsw_rs::FilterT (closures do
automatically via blanket impl).
Sourcefn delete(&self, id: usize) -> Result<()>
fn delete(&self, id: usize) -> Result<()>
Marks an ID as deleted (soft-delete).
The vector remains in the graph but is excluded from search results. HNSW graphs don’t support point removal — removing nodes breaks proximity edges that other nodes rely on.
Sourcefn is_deleted(&self, id: usize) -> bool
fn is_deleted(&self, id: usize) -> bool
Returns true if the given ID is marked as deleted.