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

Method from_checkpoint

nodedb-vector/src/collection/checkpoint.rs:248–406  ·  view source on GitHub ↗

Restore a collection from checkpoint bytes. `kek` controls the expected framing: - `None` → the file must be plaintext MessagePack (starting with bytes that are NOT `SEGV`). If the file starts with `SEGV` and no key is provided, returns `Err(CheckpointEncryptedNoKey)`. - `Some(key)` → encryption is **required**. If the file starts with `SEGV`, it is decrypted with `key`. If the file is plaintext,

(
        bytes: &[u8],
        kek: Option<&nodedb_wal::crypto::WalEncryptionKey>,
    )

Source from the content-addressed store, hash-verified

246 /// `Err(CheckpointPlaintextKeyRequired)` — refuse to silently load
247 /// unencrypted data when the operator has enabled at-rest encryption.
248 pub fn from_checkpoint(
249 bytes: &[u8],
250 kek: Option<&nodedb_wal::crypto::WalEncryptionKey>,
251 ) -> Result<Option<Self>, VectorError> {
252 let is_encrypted = bytes.len() >= 4 && bytes[0..4] == SEGV_MAGIC;
253
254 let msgpack: Vec<u8>;
255 let msgpack_ref: &[u8];
256
257 if is_encrypted {
258 if let Some(key) = kek {
259 msgpack = decrypt_checkpoint(key, bytes)?;
260 msgpack_ref = &msgpack;
261 } else {
262 return Err(VectorError::CheckpointEncryptedNoKey);
263 }
264 } else if kek.is_some() {
265 return Err(VectorError::CheckpointPlaintextKeyRequired);
266 } else {
267 msgpack_ref = bytes;
268 }
269
270 let snap: CollectionSnapshot = match zerompk::from_msgpack(msgpack_ref) {
271 Ok(s) => s,
272 Err(_) => return Ok(None),
273 };
274 let metric = match snap.params_metric {
275 0 => DistanceMetric::L2,
276 1 => DistanceMetric::Cosine,
277 2 => DistanceMetric::InnerProduct,
278 3 => DistanceMetric::Manhattan,
279 4 => DistanceMetric::Chebyshev,
280 5 => DistanceMetric::Hamming,
281 6 => DistanceMetric::Jaccard,
282 7 => DistanceMetric::Pearson,
283 _ => DistanceMetric::Cosine,
284 };
285 let params = HnswParams {
286 m: snap.params_m,
287 m0: snap.params_m0,
288 ef_construction: snap.params_ef_construction,
289 metric,
290 dtype: nodedb_types::vector_dtype::VectorStorageDtype::F32,
291 };
292
293 let mut growing = FlatIndex::new(snap.dim, metric);
294 for (i, v) in snap.growing_vectors.iter().enumerate() {
295 let deleted = snap.growing_deleted.get(i).copied().unwrap_or(false);
296 if deleted {
297 growing.insert_tombstoned(v.clone());
298 } else {
299 growing.insert(v.clone());
300 }
301 }
302
303 let mut sealed = Vec::with_capacity(snap.sealed_segments.len());
304 for ss in &snap.sealed_segments {
305 if let Some(index) = HnswIndex::from_checkpoint(&ss.hnsw_bytes).ok().flatten() {

Callers

nothing calls this directly

Calls 14

decrypt_checkpointFunction · 0.85
quantization_from_tagFunction · 0.85
insert_tombstonedMethod · 0.80
collectMethod · 0.80
lenMethod · 0.45
iterMethod · 0.45
getMethod · 0.45
cloneMethod · 0.45
insertMethod · 0.45
okMethod · 0.45
pushMethod · 0.45
expectMethod · 0.45

Tested by

no test coverage detected