MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / insert

Method insert

nodedb-vector/src/codec_index/build.rs:45–127  ·  view source on GitHub ↗

Insert a vector with the given caller-supplied `id`. Encodes `v` via `codec.encode`, assigns a random layer, and runs the standard HNSW neighbour-selection algorithm.

(&mut self, id: u32, v: &[f32])

Source from the content-addressed store, hash-verified

43 /// Encodes `v` via `codec.encode`, assigns a random layer, and runs the
44 /// standard HNSW neighbour-selection algorithm.
45 pub fn insert(&mut self, id: u32, v: &[f32]) {
46 let quantized = self.codec.encode(v);
47 let node_layer = self.random_layer();
48
49 // Allocate the node first so we can use its index in the graph wiring.
50 let new_idx = self.nodes.len() as u32;
51
52 // Build empty neighbor lists: one per layer 0..=node_layer.
53 let neighbors = vec![Vec::new(); node_layer + 1];
54
55 self.nodes.push(NodeC {
56 id,
57 deleted: false,
58 layer: node_layer,
59 quantized,
60 neighbors,
61 });
62
63 let Some(ep) = self.entry_point else {
64 // First node: it becomes the entry point.
65 self.entry_point = Some(new_idx);
66 self.max_layer = node_layer;
67 return;
68 };
69
70 // Phase 1: greedy descent from max_layer down to node_layer + 1.
71 // Carry a single nearest candidate per layer (ef = 1).
72 let mut cur_ep = ep;
73 for layer in (node_layer + 1..=self.max_layer).rev() {
74 cur_ep = self.greedy_nearest(new_idx, cur_ep, layer);
75 }
76
77 // Phase 2: ef_construction search from node_layer down to 0.
78 let ef = self.ef_construction;
79 for layer in (0..=node_layer.min(self.max_layer)).rev() {
80 let candidates = self.search_layer_build(new_idx, cur_ep, ef, layer);
81
82 // Choose the m (or m0 at layer 0) nearest as neighbours.
83 let max_nb = self.max_neighbors(layer);
84 let chosen: Vec<u32> = candidates
85 .iter()
86 .filter(|c| c.idx != new_idx)
87 .take(max_nb)
88 .map(|c| c.idx)
89 .collect();
90
91 // Set new node's neighbours at this layer.
92 self.nodes[new_idx as usize].neighbors[layer] = chosen.clone();
93
94 // Update chosen neighbours reciprocally.
95 for &nb_idx in &chosen {
96 let new_dist = {
97 let nb_q = &self.nodes[nb_idx as usize].quantized as *const C::Quantized;
98 let new_q = &self.nodes[new_idx as usize].quantized as *const C::Quantized;
99 // SAFETY: we hold exclusive access to `self`; the two
100 // borrows are to distinct nodes.
101 unsafe { self.codec.fast_symmetric_distance(&*nb_q, &*new_q) }
102 };

Calls 15

greedy_nearestMethod · 0.80
search_layer_buildMethod · 0.80
collectMethod · 0.80
firstMethod · 0.80
encodeMethod · 0.45
random_layerMethod · 0.45
lenMethod · 0.45
pushMethod · 0.45
max_neighborsMethod · 0.45
takeMethod · 0.45
iterMethod · 0.45
cloneMethod · 0.45