laminar_storage/incremental/mod.rs
1//! # Incremental Checkpointing
2//!
3//! Three-tier incremental checkpoint architecture that maintains Ring 0 latency (<500ns)
4//! while providing durable, incremental state snapshots.
5//!
6//! ## Architecture
7//!
8//! ```text
9//! Ring 0 (Hot, <500ns):
10//! Event ──▶ mmap_state.put() ──▶ changelog.push(offset_ref)
11//! (zero-alloc)
12//! │
13//! ▼ async drain when idle
14//! Ring 1 (Background):
15//! changelog.drain() ──▶ wal.append() ──▶ wal.sync()
16//! (group commit, fdatasync)
17//! │
18//! ▼ periodic checkpoint
19//! wal.replay(last_ckpt..now) ──▶ state.apply_batch()
20//! state.create_checkpoint() ──▶ snapshot to directory
21//! wal.truncate(checkpoint_epoch)
22//! ```
23//!
24//! ## Core Invariant
25//!
26//! ```text
27//! Checkpoint(epoch) + WAL.replay(epoch..current) = Consistent State
28//! ```
29//!
30//! ## Key Components
31//!
32//! - [`StateChangelogEntry`]: Zero-alloc changelog entry (32 bytes)
33//! - [`StateChangelogBuffer`]: Ring 0 SPSC changelog buffer
34//! - [`IncrementalCheckpointManager`]: Directory-based incremental checkpoints
35//! - [`RecoveryManager`]: Checkpoint + WAL recovery
36//!
37//! ## Example
38//!
39//! ```rust,no_run
40//! use laminar_storage::incremental::{
41//! IncrementalCheckpointManager, CheckpointConfig, RecoveryConfig, RecoveryManager,
42//! };
43//! use std::path::Path;
44//! use std::time::Duration;
45//!
46//! // Create checkpoint manager
47//! let config = CheckpointConfig::new(Path::new("/data/checkpoints"))
48//! .with_wal_path(Path::new("/data/wal"))
49//! .with_interval(Duration::from_secs(60))
50//! .with_max_retained(3);
51//!
52//! let mut manager = IncrementalCheckpointManager::new(config).unwrap();
53//!
54//! // Create incremental checkpoint
55//! let metadata = manager.create_checkpoint(100).unwrap();
56//! println!("Created checkpoint {} at epoch {}", metadata.id, metadata.epoch);
57//!
58//! // Recovery
59//! let recovery_config = RecoveryConfig::new(Path::new("/data/checkpoints"), Path::new("/data/wal"));
60//! let recovery_manager = RecoveryManager::new(recovery_config);
61//! let recovered = recovery_manager.recover().unwrap();
62//! println!("Recovered to epoch {} with {} source offsets",
63//! recovered.epoch, recovered.source_offsets.len());
64//! ```
65
66mod changelog;
67mod error;
68mod manager;
69mod recovery;
70
71pub use changelog::{StateChangelogBuffer, StateChangelogEntry, StateOp};
72pub use error::IncrementalCheckpointError;
73pub use manager::{CheckpointConfig, IncrementalCheckpointManager, IncrementalCheckpointMetadata};
74pub use recovery::{
75 validate_checkpoint, wal_size, RecoveredState, RecoveryConfig, RecoveryManager,
76};