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

Function build_sidecar

nodedb-vector/src/collection/sidecar_build.rs:37–147  ·  view source on GitHub ↗

Build a [`CodecSidecar`] for the given quantization over all provided (id, vec) pairs. - `quantization == None` → returns `Ok(None)` (no sidecar needed). - `Sq8` / `Binary` → no external training needed; codec is functional after `new`. - `Pq` / `RaBitQ` / `Bbq` → trains from the provided sample vectors (capped at `MAX_TRAINING_SAMPLES` for efficiency), then encodes all vectors. - `Ternary` / `Op

(
    quantization: VectorQuantization,
    dim: usize,
    samples: &[(u32, Vec<f32>)],
)

Source from the content-addressed store, hash-verified

35/// encode failures emit a `tracing::warn` and are skipped; the sidecar may be
36/// partially populated in that case, and affected rows degrade to FP32 rerank.
37pub(crate) fn build_sidecar(
38 quantization: VectorQuantization,
39 dim: usize,
40 samples: &[(u32, Vec<f32>)],
41) -> Result<Option<CodecSidecar>, VectorError> {
42 if samples.is_empty() {
43 // Nothing to train on or encode — return an empty sidecar for non-None quantizations
44 // so the collection is marked as having one (future inserts will populate it).
45 if quantization == VectorQuantization::None {
46 return Ok(None);
47 }
48 }
49
50 let codec: Arc<dyn RerankCodec> = match quantization {
51 VectorQuantization::None => return Ok(None),
52
53 VectorQuantization::Sq8 => {
54 let mut codec = Sq8Rerank::new(dim);
55 if !samples.is_empty() {
56 let vecs: Vec<&[f32]> = samples
57 .iter()
58 .take(MAX_TRAINING_SAMPLES)
59 .map(|(_, v)| v.as_slice())
60 .collect();
61 codec
62 .train(&vecs)
63 .map_err(|e| VectorError::BadInput(format!("sq8 sidecar train failed: {e}")))?;
64 }
65 Arc::new(codec)
66 }
67
68 VectorQuantization::Binary => {
69 // Binary has no learned state — new() is fully functional.
70 Arc::new(BinaryRerank::new(dim))
71 }
72
73 VectorQuantization::Pq => {
74 let mut codec = PqRerank::new(dim, 8, 256);
75 if !samples.is_empty() {
76 let vecs: Vec<&[f32]> = samples
77 .iter()
78 .take(MAX_TRAINING_SAMPLES)
79 .map(|(_, v)| v.as_slice())
80 .collect();
81 codec
82 .train(&vecs)
83 .map_err(|e| VectorError::BadInput(format!("pq sidecar train failed: {e}")))?;
84 }
85 Arc::new(codec)
86 }
87
88 VectorQuantization::RaBitQ => {
89 let mut codec = RaBitQRerank::new(dim, DEFAULT_ROTATION_SEED);
90 if !samples.is_empty() {
91 let vecs: Vec<&[f32]> = samples
92 .iter()
93 .take(MAX_TRAINING_SAMPLES)
94 .map(|(_, v)| v.as_slice())

Callers

nothing calls this directly

Calls 7

collectMethod · 0.80
encode_and_insertMethod · 0.80
is_emptyMethod · 0.45
takeMethod · 0.45
iterMethod · 0.45
as_sliceMethod · 0.45
trainMethod · 0.45

Tested by

no test coverage detected