lora_store/snapshot.rs
1//! Snapshot value types — the portable payload + metadata + error
2//! vocabulary every backend speaks.
3//!
4//! The on-disk snapshot container lives in the [`lora-snapshot`] crate
5//! (column-oriented, optionally compressed and authenticated). Backends
6//! produce a [`SnapshotPayload`] through their inherent helpers (e.g.
7//! [`super::InMemoryGraph::snapshot_payload`]); `lora-snapshot` encodes
8//! that payload and reuses the small store-owned binary codec for nested
9//! value/catalog records.
10
11use serde::{Deserialize, Serialize};
12use thiserror::Error;
13
14use crate::memory::{ConstraintDefinition, IndexDefinition};
15use crate::{NodeId, NodeRecord, RelationshipId, RelationshipRecord};
16
17/// Portable representation of an entire store state.
18///
19/// Backends produce and consume this struct through inherent helpers;
20/// the byte-level codec is owned by `lora-snapshot`.
21#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
22pub struct SnapshotPayload {
23 pub next_node_id: NodeId,
24 pub next_rel_id: RelationshipId,
25 pub nodes: Vec<NodeRecord>,
26 pub relationships: Vec<RelationshipRecord>,
27 /// Catalog of explicitly-declared indexes. Defaulted to empty so
28 /// older snapshots that lack the trailer round-trip cleanly.
29 #[serde(default)]
30 pub indexes: Vec<IndexDefinition>,
31 /// Catalog of explicitly-declared constraints. Defaulted to empty
32 /// so snapshots from versions before constraint support survive
33 /// the round-trip.
34 #[serde(default)]
35 pub constraints: Vec<ConstraintDefinition>,
36}
37
38impl SnapshotPayload {
39 pub fn empty() -> Self {
40 Self {
41 next_node_id: 0,
42 next_rel_id: 0,
43 nodes: Vec::new(),
44 relationships: Vec::new(),
45 indexes: Vec::new(),
46 constraints: Vec::new(),
47 }
48 }
49}
50
51/// Metadata reported by snapshot encode / decode entry points. Kept
52/// small and stable so callers can log / diff it without reflecting on
53/// the payload.
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55pub struct SnapshotMeta {
56 /// Format version the payload is written in.
57 pub format_version: u32,
58 /// Number of nodes in the snapshot.
59 pub node_count: usize,
60 /// Number of relationships in the snapshot.
61 pub relationship_count: usize,
62 /// WAL log position captured alongside the snapshot, if any. `None` for
63 /// pure (non-checkpoint) snapshots.
64 pub wal_lsn: Option<u64>,
65}
66
67/// Errors a backend may surface while building or restoring a snapshot
68/// payload. Codec-level errors live in [`lora-snapshot`]; these are the
69/// store-side payload-shaped failures.
70#[derive(Debug, Error)]
71pub enum SnapshotError {
72 #[error("snapshot I/O error: {0}")]
73 Io(#[from] std::io::Error),
74
75 #[error("snapshot payload could not be decoded: {0}")]
76 Decode(String),
77
78 #[error("snapshot payload could not be encoded: {0}")]
79 Encode(String),
80}