weavatrix-search-vector 0.3.1

Persistent, mutable, bounded vector candidate search for Rust and Weavatrix
Documentation
mod codec;
mod format;
mod io;
mod mutable_api;
mod reader;
mod validation;
mod writer;

use crate::error::SearchError;
use crate::mutable::MutableVectorIndex;
use crate::quantized::QuantizedIndex;
use std::path::Path;

/// Atomic persistence unit for mutable f32 state and an optional compact
/// representation.
#[derive(Debug)]
pub struct IndexBundle {
    mutable: MutableVectorIndex,
    quantized: Option<QuantizedIndex>,
}

impl IndexBundle {
    /// Creates a validated bundle.
    ///
    /// # Errors
    ///
    /// Returns an error when the compact representation does not describe the
    /// same active key set and configuration as the mutable index.
    pub fn new(
        mutable: MutableVectorIndex,
        quantized: Option<QuantizedIndex>,
    ) -> Result<Self, SearchError> {
        validation::validate_quantized(&mutable.snapshot(), quantized.as_ref())?;
        Ok(Self { mutable, quantized })
    }

    /// Returns the mutable f32 index and its delta/metadata state.
    #[must_use]
    pub const fn mutable(&self) -> &MutableVectorIndex {
        &self.mutable
    }

    /// Returns mutable access to the f32 index.
    ///
    /// Callers replacing active vectors must also replace or remove the
    /// compact representation before saving.
    #[must_use]
    pub const fn mutable_mut(&mut self) -> &mut MutableVectorIndex {
        &mut self.mutable
    }

    /// Returns the optional compact representation.
    #[must_use]
    pub const fn quantized(&self) -> Option<&QuantizedIndex> {
        self.quantized.as_ref()
    }

    /// Replaces the compact representation after validating bundle identity.
    ///
    /// # Errors
    ///
    /// Returns an error when config or active keys differ.
    pub fn set_quantized(&mut self, quantized: Option<QuantizedIndex>) -> Result<(), SearchError> {
        validation::validate_quantized(&self.mutable.snapshot(), quantized.as_ref())?;
        self.quantized = quantized;
        Ok(())
    }

    /// Consumes the bundle.
    #[must_use]
    pub fn into_parts(self) -> (MutableVectorIndex, Option<QuantizedIndex>) {
        (self.mutable, self.quantized)
    }

    /// Atomically saves vectors, graphs, mutation delta, metadata, and compact
    /// representation under one checksum.
    ///
    /// # Errors
    ///
    /// Returns a consistency, serialization, or filesystem error.
    pub fn save(&self, path: impl AsRef<Path>) -> Result<(), SearchError> {
        writer::save_complete(&self.mutable, self.quantized.as_ref(), path.as_ref())
    }

    /// Loads and validates a complete bundle.
    ///
    /// # Errors
    ///
    /// Returns a filesystem, integrity, format, or consistency error.
    pub fn load(path: impl AsRef<Path>) -> Result<Self, SearchError> {
        let (mutable, quantized) = reader::load_complete(path.as_ref())?;
        Self::new(mutable, quantized)
    }
}