Skip to main content

mongreldb_core/
page.rs

1use crate::epoch::Epoch;
2use serde::{Deserialize, Serialize};
3
4/// On-disk page encoding. Mirrors the strategies used by modern columnar
5/// formats, plus `BinaryQuantized` for AI embedding columns.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[repr(u8)]
8pub enum Encoding {
9    Plain = 0,
10    Dictionary = 1,
11    Delta = 2,
12    ByteStreamSplit = 3,
13    RunLength = 4,
14    /// 1 bit per dimension; similarity via SIMD popcount(XOR).
15    BinaryQuantized = 5,
16    /// Plain-encode then zstd-compress (default for fixed-width and high-card columns).
17    Zstd = 6,
18}
19
20/// Per-page statistics enabling file/page-level pruning (analogous to Parquet's
21/// page index, but always present and tighter). Serialized in the run's column
22/// directory.
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct PageStat {
25    pub first_row_id: u64,
26    pub last_row_id: u64,
27    pub null_count: u64,
28    pub row_count: u32,
29    pub min: Option<Vec<u8>>,
30    pub max: Option<Vec<u8>>,
31    /// Absolute offset of the (possibly encrypted + compressed) page payload.
32    pub offset: u64,
33    pub compressed_len: u32,
34    pub uncompressed_len: u32,
35}
36
37/// A cached, decrypted, decompressed page tagged with the epoch at which it was
38/// committed. The tag is what makes the cache self-invalidating under MVCC.
39#[derive(Debug, Clone)]
40pub struct CachedPage {
41    pub committed_epoch: Epoch,
42    pub content_hash: [u8; 32],
43    pub bytes: bytes::Bytes,
44}
45
46impl CachedPage {
47    /// Cache key for content-addressed, MVCC-safe storage.
48    pub fn cache_key(&self) -> ([u8; 32], Epoch) {
49        (self.content_hash, self.committed_epoch)
50    }
51}