nodedb_lite/engine/vector/
nodes.rs1use std::sync::Arc;
11
12use crate::engine::vector::resident::lock_resident_or_create;
13use crate::engine::vector::{HnswIndex, VectorState};
14use crate::error::LiteError;
15use crate::nodedb::lock_ext::LockExt;
16use crate::storage::engine::StorageEngine;
17
18pub(crate) fn bind_node<S: StorageEngine>(
24 state: &VectorState<S>,
25 index: &mut HnswIndex,
26 index_key: &str,
27 doc_id: &str,
28 embedding: Vec<f32>,
29) -> Result<u32, LiteError> {
30 let node = index.len() as u32;
31 index.insert(embedding)?;
32 let displaced = state
33 .vector_id_map
34 .lock_or_recover()
35 .bind(index_key, doc_id, node);
36 if let Some(old) = displaced {
37 index.delete(old);
38 drop_sidecar_code(state, index_key, old);
39 }
40 Ok(node)
41}
42
43pub(crate) fn unbind_node<S: StorageEngine>(
47 state: &VectorState<S>,
48 index: Option<&mut HnswIndex>,
49 index_key: &str,
50 doc_id: &str,
51) -> Option<u32> {
52 let node = state
53 .vector_id_map
54 .lock_or_recover()
55 .unbind_doc(index_key, doc_id)?;
56 if let Some(index) = index {
57 index.delete(node);
58 }
59 drop_sidecar_code(state, index_key, node);
60 Some(node)
61}
62
63pub(crate) async fn upsert_node<S: StorageEngine>(
68 state: &Arc<VectorState<S>>,
69 index_key: &str,
70 doc_id: &str,
71 embedding: &[f32],
72) -> Result<u32, LiteError> {
73 let mut resident = lock_resident_or_create(state, index_key, embedding.len()).await?;
74 bind_node(
75 state,
76 resident.index(),
77 index_key,
78 doc_id,
79 embedding.to_vec(),
80 )
81}
82
83pub(crate) fn encode_sidecar<S: StorageEngine>(
90 state: &VectorState<S>,
91 index_key: &str,
92 node: u32,
93 embedding: &[f32],
94) -> Result<(), LiteError> {
95 if !crate::engine::vector::sidecar::ensure_sidecar(state, index_key)? {
96 return Ok(());
97 }
98 let mut sidecars = state.codec_sidecars.lock_or_recover();
99 if let Some(sidecar) = sidecars.get_mut(index_key)
100 && let Err(e) = sidecar.encode_and_insert(node, embedding)
101 {
102 tracing::warn!(
103 index_key,
104 id = node,
105 error = %e,
106 "sidecar encode_and_insert failed; row falls back to FP32 rerank"
107 );
108 }
109 Ok(())
110}
111
112fn drop_sidecar_code<S: StorageEngine>(state: &VectorState<S>, index_key: &str, node: u32) {
114 if let Some(sidecar) = state.codec_sidecars.lock_or_recover().get_mut(index_key) {
115 sidecar.remove(node);
116 }
117}