hnsw/
lib.rs

1#![no_std]
2extern crate alloc;
3
4mod hnsw;
5
6pub use self::hnsw::*;
7
8use ahash::RandomState;
9use alloc::{vec, vec::Vec};
10use hashbrown::HashSet;
11use space::Neighbor;
12
13#[cfg(feature = "serde")]
14use serde::{Deserialize, Serialize};
15
16#[derive(Copy, Clone, Debug)]
17#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
18pub struct Params {
19    ef_construction: usize,
20}
21
22impl Params {
23    pub fn new() -> Self {
24        Default::default()
25    }
26
27    /// This is refered to as `efConstruction` in the paper. This is equivalent to the `ef` parameter passed
28    /// to `nearest`, but it is the `ef` used when inserting elements. The higher this is, the more likely the
29    /// nearest neighbors in each graph level will be correct, leading to a higher recall rate and speed when
30    /// calling `nearest`. This parameter greatly affects the speed of insertion into the HNSW.
31    ///
32    /// This parameter is probably the only one that in important to tweak.
33    ///
34    /// Defaults to `400` (overkill for most tasks, but only lower after profiling).
35    pub fn ef_construction(mut self, ef_construction: usize) -> Self {
36        self.ef_construction = ef_construction;
37        self
38    }
39}
40
41impl Default for Params {
42    fn default() -> Self {
43        Self {
44            ef_construction: 400,
45        }
46    }
47}
48
49/// Contains all the state used when searching the HNSW
50#[derive(Clone, Debug)]
51pub struct Searcher<Metric> {
52    candidates: Vec<Neighbor<Metric>>,
53    nearest: Vec<Neighbor<Metric>>,
54    seen: HashSet<usize, RandomState>,
55}
56
57impl<Metric> Searcher<Metric> {
58    pub fn new() -> Self {
59        Default::default()
60    }
61
62    fn clear(&mut self) {
63        self.candidates.clear();
64        self.nearest.clear();
65        self.seen.clear();
66    }
67}
68
69impl<Metric> Default for Searcher<Metric> {
70    fn default() -> Self {
71        Self {
72            candidates: vec![],
73            nearest: vec![],
74            seen: HashSet::with_hasher(RandomState::with_seeds(0, 0, 0, 0)),
75        }
76    }
77}