walogs/lib.rs
1//! A crash-safe write-ahead log (WAL) library for Rust.
2//!
3//! `walogs` gives you a durable, append-only sequence of byte entries with
4//! automatic crash recovery. Every successful [`Wal::append`] call has been
5//! `fdatasync`'d before it returns `Ok`. On the next [`Wal::open`], any
6//! partial (torn) write at the tail is detected and truncated automatically.
7//!
8//! # Quick start
9//!
10//! ```no_run
11//! use walogs::{Wal, Lsn, TailState};
12//!
13//! // Open or create a WAL directory.
14//! let mut wal = Wal::open(std::path::Path::new("/tmp/my-wal")).unwrap();
15//!
16//! // Append entries — each Ok means durable on disk.
17//! let _lsn1 = wal.append(b"first entry").unwrap();
18//! let lsn2 = wal.append(b"second entry").unwrap();
19//!
20//! // Iterate all entries.
21//! for result in wal.iter() {
22//! let (lsn, data) = result.unwrap();
23//! println!("lsn={} data={:?}", lsn.0, data);
24//! }
25//!
26//! // Checkpoint: delete completed segments up to and including lsn2.
27//! wal.checkpoint(lsn2).unwrap();
28//!
29//! // Recovery is automatic on the next open.
30//! let wal = Wal::open(std::path::Path::new("/tmp/my-wal")).unwrap();
31//! match wal.tail_state() {
32//! TailState::Clean => {}
33//! TailState::TruncatedAt(offset) => {
34//! println!("crash recovery: partial write discarded at offset {offset}");
35//! }
36//! }
37//! ```
38//!
39//! # Guarantees
40//!
41//! - **Durable on `Ok`** — `fdatasync` completes before `append` returns `Ok`.
42//! - **At most one lost write after a crash** — the last in-flight write may be
43//! lost; every prior entry is guaranteed intact.
44//! - **Dense LSNs** — LSNs are `1, 2, 3, …` with no gaps across all segments.
45//! - **No buried garbage** — corrupt tails are truncated before any new write.
46//! - **Segment integrity** — LSN continuity and sequence gaps are detected on open.
47//!
48//! # What this library does NOT do
49//!
50//! - No transactions or multi-entry atomicity.
51//! - No file locking — callers must ensure a single writer per directory.
52//! - No async API.
53//! - No seek-by-LSN; [`Wal::iter`] walks the whole log from the beginning.
54
55mod error;
56mod frame;
57mod segment;
58mod wal;
59
60pub use error::WalError;
61pub use frame::MAX_ENTRY_SIZE;
62pub use wal::{Lsn, TailState, Wal, WalConfig, WalIter};