Skip to main content

HnswIndex

Struct HnswIndex 

Source
pub struct HnswIndex { /* private fields */ }
Expand description

Main HNSW vector search index

Provides approximate nearest neighbor search capabilities using the Hierarchical Navigable Small World algorithm. Integrates with SQLiteGraph to provide vector-augmented graph queries.

§Performance Characteristics

  • Search Time: O(log N) average case complexity
  • Memory Usage: 2-3x vector data size overhead
  • Build Time: O(N log N) with construction parameters
  • Accuracy: 95%+ recall for typical workloads

Implementations§

§

impl HnswIndex

pub fn new(name: &str, config: HnswConfig) -> Result<Self, HnswError>

Create a new HNSW index with the specified configuration

§Arguments
  • name - Name of the index (for persistence and multi-index support)
  • config - HNSW configuration parameters
§Returns

Returns a new HnswIndex ready for vector insertion and search

§Examples
use sqlitegraph::hnsw::{HnswIndex, HnswConfig, DistanceMetric};

let config = HnswConfig::builder()
    .dimension(128)
    .distance_metric(DistanceMetric::Euclidean)
    .build()?;

let hnsw = HnswIndex::new("my_index", config)?;

pub fn with_persistent_storage( name: &str, config: HnswConfig, conn: Connection, ) -> Result<Self, HnswError>

Create a new HNSW index with SQLite-backed persistent storage

§Arguments
  • name - Name of the index
  • config - HNSW configuration parameters
  • conn - SQLite connection
§Returns

Returns a new HnswIndex with SQLite storage

§Note

This creates an index with persistent storage. The index_id will be set after saving metadata to the database.

pub fn with_storage( name: &str, config: HnswConfig, storage: Box<dyn VectorStorage>, ) -> Result<Self, HnswError>

Create a new HNSW index with custom storage backend

§Arguments
  • name - Name of the index
  • config - HNSW configuration parameters
  • storage - Custom vector storage implementation
§Returns

Returns a new HnswIndex using the provided storage backend

pub fn insert_vector( &mut self, vector: &[f32], metadata: Option<Value>, ) -> Result<u64, HnswError>

Insert a vector into the HNSW index

§Arguments
  • vector - Vector data to insert (must match configured dimension)
  • metadata - Optional JSON metadata to associate with the vector
§Returns

Returns the assigned vector ID for future reference

§Errors

Returns HnswError::Index for dimension mismatches or insert failures

§Examples
let vector = vec![1.0, 0.0, 0.0];
let metadata = serde_json::json!({"label": "test"});

let vector_id = hnsw.insert_vector(&vector, Some(metadata))?;
println!("Inserted vector with ID: {}", vector_id);

pub fn search( &self, query: &[f32], k: usize, ) -> Result<Vec<(u64, f32)>, HnswError>

Search for the k nearest neighbors to a query vector

§Arguments
  • query - Query vector (must match configured dimension)
  • k - Number of nearest neighbors to return
§Returns

Returns a vector of (vector_id, distance) tuples sorted by distance

§Errors

Returns HnswError::Index for dimension mismatches or search failures

§Examples
let query = vec![1.0, 0.0, 0.0];

let results = hnsw.search(&query, 5)?;
for (id, distance) in results {
    println!("Vector {}: distance {}", id, distance);
}

pub fn get_vector( &self, vector_id: u64, ) -> Result<Option<(Vec<f32>, Value)>, HnswError>

Get vector data and metadata by ID

§Arguments
  • vector_id - ID of the vector to retrieve
§Returns

Returns Some((vector, metadata)) if found, None if not found

§Examples
let result = hnsw.get_vector(vector_id)?;
if let Some((vector, metadata)) = result {
    println!("Retrieved vector: {:?}", vector);
}

pub fn statistics(&self) -> Result<HnswIndexStats, HnswError>

Get statistics about the HNSW index

§Returns

Returns comprehensive statistics about index state and performance

§Examples
let stats = hnsw.statistics()?;
println!("Vectors indexed: {}", stats.vector_count);
println!("Layers: {}", stats.layer_count);

pub fn name(&self) -> &str

Get the name of this index

pub fn vector_count(&self) -> usize

Get the number of vectors in this index

pub fn config(&self) -> &HnswConfig

Get the HNSW configuration

Returns a reference to the index configuration

§

impl HnswIndex

pub fn save_metadata(&self, conn: &Connection) -> Result<(), HnswError>

Save index metadata to database

§Arguments
  • conn - SQLite connection
§Returns

Ok(()) if successful

§Errors

Returns HnswError on database failure

pub fn load_metadata(conn: &Connection, name: &str) -> Result<Self, HnswError>

Load index metadata from database

§Arguments
  • conn - SQLite connection
  • name - Index name
§Returns

Loaded HnswIndex with metadata (vectors not loaded yet)

§Errors

Returns HnswError on database failure or if index not found

pub fn load_vectors_and_rebuild( &mut self, conn: &Connection, ) -> Result<(), HnswError>

Load all vectors from database and rebuild HNSW index

§Arguments
  • conn - SQLite connection
§Returns

Ok(()) if successful

§Errors

Returns HnswError on database failure or vector loading errors

§Note

This method loads all vectors from the database and rebuilds the HNSW graph structure by inserting each vector. The O(N log N) rebuild cost is a trade-off for simpler implementation compared to persisting layers.

pub fn load_with_vectors( conn: &Connection, name: &str, ) -> Result<Self, HnswError>

Load index with vectors from database

§Arguments
  • conn - SQLite connection
  • name - Index name
§Returns

Fully loaded HnswIndex with all vectors

§Errors

Returns HnswError on database failure or if index not found

§Note

This is a convenience method that loads metadata and vectors in one call.

pub fn list_indexes(conn: &Connection) -> Result<Vec<String>, HnswError>

List all HNSW indexes in the database

§Arguments
  • conn - SQLite connection
§Returns

List of index names

§Errors

Returns HnswError on database failure

pub fn delete_index(conn: &Connection, name: &str) -> Result<(), HnswError>

Delete an index from the database

§Arguments
  • conn - SQLite connection
  • name - Index name
§Returns

Ok(()) if deleted or didn’t exist

§Errors

Returns HnswError on database failure

§Note

CASCADE will automatically delete vectors, layers, and entry points

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V