Skip to main content

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}