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, pub m_max: usize, pub ef_construction: usize, pub ef_search: usize, pub ml: f32, }
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(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HnswIndex {
config: HnswConfig,
entry_point: Option<usize>,
max_layer: usize,
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(),
}
}
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
}
}