Skip to main content

page_db/
lib.rs

1//! # page-db
2//!
3//! The paging substrate beneath B-tree and heap storage engines: fixed-size
4//! pages on disk, each carrying a versioned header with a CRC32C integrity
5//! check and an LSN slot for write-ahead-log coordination, read and written
6//! through cross-platform Direct I/O that bypasses the OS page cache.
7//!
8//! This is the v0.2.0 layer: the page format and the durable file underneath
9//! it. The LRU buffer pool, pinning, and the page allocator land in later 0.x
10//! releases (see `dev/ROADMAP.md`). The buffer pool that will sit on top of
11//! [`PageFile`] is not here yet; today you read and write pages straight
12//! through to disk.
13//!
14//! ## The shape of it
15//!
16//! A [`PageFile`] is an array of fixed-size [`Page`]s addressed by [`PageId`].
17//! Every page carries a header; on write the header's checksum is stamped over
18//! the page bytes, and on read it is verified before the page is handed back —
19//! a corrupt or misdirected page is a typed [`PageError`], never a silent read.
20//!
21//! ```no_run
22//! use page_db::{PageFile, PageId, Lsn};
23//!
24//! # fn main() -> Result<(), page_db::PageError> {
25//! // A 4 KiB-page file, Direct I/O, created if absent.
26//! let file = PageFile::open("data.pages", page_db::DEFAULT_PAGE_SIZE)?;
27//!
28//! // Allocate a fresh page, fill its payload, tag it with a log sequence number.
29//! let mut page = file.allocate_page();
30//! page.set_lsn(Lsn::new(1));
31//! page.payload_mut()[..5].copy_from_slice(b"hello");
32//!
33//! // Write it to slot 0 and make it durable.
34//! let id = PageId::new(0);
35//! file.write_page(id, &mut page)?;
36//! file.sync()?;
37//!
38//! // Read it back — the header and checksum are verified on the way out.
39//! let read = file.read_page(id)?;
40//! assert_eq!(&read.payload()[..5], b"hello");
41//! assert_eq!(read.lsn(), Lsn::new(1));
42//! # Ok(())
43//! # }
44//! ```
45
46#![cfg_attr(docsrs, feature(doc_cfg))]
47#![deny(missing_docs)]
48#![deny(unsafe_op_in_unsafe_fn)]
49#![deny(unused_must_use)]
50#![deny(unused_results)]
51#![deny(clippy::unwrap_used)]
52#![deny(clippy::expect_used)]
53#![deny(clippy::todo)]
54#![deny(clippy::unimplemented)]
55#![deny(clippy::print_stdout)]
56#![deny(clippy::print_stderr)]
57#![deny(clippy::dbg_macro)]
58#![deny(clippy::undocumented_unsafe_blocks)]
59
60mod buffer;
61pub mod checksum;
62mod error;
63mod file;
64mod page;
65mod sys;
66
67pub use crate::checksum::crc32c;
68pub use crate::error::{PageError, PageResult};
69pub use crate::file::{PageFile, PageFileOptions};
70pub use crate::page::{
71    DEFAULT_PAGE_SIZE, Lsn, MAX_PAGE_SIZE, MIN_PAGE_SIZE, PAGE_HEADER_SIZE, Page, PageId, PageSize,
72};