veclite-core 0.1.0

Core query and execution engine for VecLite
Documentation
use std::collections::{HashMap, HashSet};
use std::cmp::Reverse;
use rand::Rng;
use serde::{Serialize, Deserialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HnswConfig {
    pub m: usize,            // Max number of connections per layer
    pub m_max: usize,        // Max connections for layer 0
    pub ef_construction: usize, // Size of dynamic candidate list during construction
    pub ef_search: usize,    // Size of dynamic candidate list during search
    pub ml: f32,             // Level generation factor (1 / ln(m))
}

impl Default for HnswConfig {
    fn default() -> Self {
        Self {
            m: 16,
            m_max: 32,
            ef_construction: 200,
            ef_search: 64,
            ml: 1.0 / 16.0f32.ln(),
        }
    }
}

// A minimal scaffolding of the HNSW structure to be integrated fully later
// This prepares the architecture for Phase 2's indexing requirements.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HnswIndex {
    config: HnswConfig,
    entry_point: Option<usize>,
    max_layer: usize,
    // Node ID -> Layer -> Vec<Neighbor IDs>
    graph: HashMap<usize, Vec<Vec<usize>>>,
}

impl HnswIndex {
    pub fn new(config: HnswConfig) -> Self {
        Self {
            config,
            entry_point: None,
            max_layer: 0,
            graph: HashMap::new(),
        }
    }

    // Scaffolding: random layer generation based on paper
    fn random_layer(&self) -> usize {
        let mut rng = rand::thread_rng();
        let unif: f32 = rng.gen_range(0.0..1.0);
        (-unif.ln() * self.config.ml).floor() as usize
    }
}