Skip to main content

zeppelin_embed/format/
mod.rs

1//! Append-only persisted-format registry.
2
3pub mod frame;
4pub mod golden;
5
6/// A persisted artifact family identifier.
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8#[repr(u16)]
9pub enum FormatFamily {
10    /// Generic length-prefixed framing.
11    Frame = 1,
12    /// Immutable segment files.
13    Segment = 2,
14    /// Packed vector-code regions.
15    VectorCodes = 3,
16    /// Quantizer factor-record regions.
17    VectorFactors = 4,
18    /// Exact-rescore vector regions.
19    VectorRescore = 5,
20    /// Typed metadata-column regions.
21    Columns = 6,
22    /// Alive/tombstone regions.
23    Alive = 7,
24    /// Reserved full-text postings regions.
25    Postings = 8,
26    /// Per-chunk xxh3 checksum tables.
27    ChecksumTable = 9,
28    /// Store manifests.
29    Manifest = 10,
30    /// Append-only write-ahead-log records.
31    Wal = 11,
32    /// Fixed-stride graph node-block regions.
33    GraphNodeBlocks = 12,
34    /// Dense sealed-row document identifiers and revisions.
35    DocumentVersions = 13,
36    /// Dense length-delimited opaque stored metadata rows.
37    StoredMetadata = 14,
38    /// Durable request proving an unfinished physical purge must resume.
39    PurgeIntent = 15,
40    /// Dense optional UTF-8 source text aligned to sealed rows.
41    StoredText = 16,
42    /// Required immutable native property-graph object containers.
43    NativeGraphObject = 17,
44    /// Required graph root envelopes; logical checkpoint admission is separate.
45    NativeGraphRoot = 18,
46    /// Required complete native graph WAL envelopes.
47    NativeGraphWal = 19,
48}
49
50impl FormatFamily {
51    /// Returns the permanent numeric family identifier.
52    #[must_use]
53    pub const fn id(self) -> u16 {
54        self as u16
55    }
56
57    pub(crate) const fn current_version(self) -> u16 {
58        match self {
59            Self::Manifest => 2,
60            Self::Frame
61            | Self::Segment
62            | Self::VectorCodes
63            | Self::VectorFactors
64            | Self::VectorRescore
65            | Self::Columns
66            | Self::Alive
67            | Self::Postings
68            | Self::ChecksumTable
69            | Self::Wal
70            | Self::GraphNodeBlocks
71            | Self::DocumentVersions
72            | Self::StoredMetadata
73            | Self::PurgeIntent
74            | Self::StoredText
75            | Self::NativeGraphObject
76            | Self::NativeGraphRoot
77            | Self::NativeGraphWal => 1,
78        }
79    }
80}
81
82/// One append-only version declaration.
83#[derive(Clone, Copy, Debug, Eq, PartialEq)]
84pub struct FamilySpec {
85    /// The persisted family.
86    pub family: FormatFamily,
87    /// The version emitted by writers.
88    pub current_version: u16,
89    /// Lowest version accepted by readers.
90    pub minimum_accepted_version: u16,
91    /// Highest version accepted by readers.
92    pub maximum_accepted_version: u16,
93}
94
95/// Registry validation failure.
96#[derive(Clone, Copy, Debug, Eq, PartialEq)]
97pub enum RegistryError {
98    /// No persisted family owns this identifier.
99    UnknownFamily(u16),
100    /// The declared version is outside the reader's accepted interval.
101    UnsupportedVersion {
102        /// Artifact family identifier.
103        family: u16,
104        /// Version found in the artifact.
105        version: u16,
106        /// Lowest accepted version.
107        minimum: u16,
108        /// Highest accepted version.
109        maximum: u16,
110    },
111    /// A retired quantization scheme identifier was requested.
112    RetiredScheme(u16),
113    /// No quantization scheme owns this identifier.
114    UnknownScheme(u16),
115}
116
117impl std::fmt::Display for RegistryError {
118    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119        match self {
120            Self::UnknownFamily(family) => write!(formatter, "unknown format family {family}"),
121            Self::UnsupportedVersion {
122                family,
123                version,
124                minimum,
125                maximum,
126            } => write!(
127                formatter,
128                "format family {family} version {version} is outside accepted range {minimum}..={maximum}"
129            ),
130            Self::RetiredScheme(scheme) => {
131                write!(
132                    formatter,
133                    "quantization scheme id {scheme} is permanently retired"
134                )
135            }
136            Self::UnknownScheme(scheme) => {
137                write!(formatter, "unknown quantization scheme {scheme}")
138            }
139        }
140    }
141}
142
143impl std::error::Error for RegistryError {}
144
145/// Static registry for every persisted family and quantization identifier.
146pub struct FormatRegistry;
147
148const FAMILIES: [FamilySpec; 19] = [
149    FamilySpec {
150        family: FormatFamily::Frame,
151        current_version: 1,
152        minimum_accepted_version: 1,
153        maximum_accepted_version: 1,
154    },
155    FamilySpec {
156        family: FormatFamily::Segment,
157        current_version: 1,
158        minimum_accepted_version: 1,
159        maximum_accepted_version: 1,
160    },
161    FamilySpec {
162        family: FormatFamily::VectorCodes,
163        current_version: 1,
164        minimum_accepted_version: 1,
165        maximum_accepted_version: 1,
166    },
167    FamilySpec {
168        family: FormatFamily::VectorFactors,
169        current_version: 1,
170        minimum_accepted_version: 1,
171        maximum_accepted_version: 1,
172    },
173    FamilySpec {
174        family: FormatFamily::VectorRescore,
175        current_version: 1,
176        minimum_accepted_version: 1,
177        maximum_accepted_version: 1,
178    },
179    FamilySpec {
180        family: FormatFamily::Columns,
181        current_version: 1,
182        minimum_accepted_version: 1,
183        maximum_accepted_version: 1,
184    },
185    FamilySpec {
186        family: FormatFamily::Alive,
187        current_version: 1,
188        minimum_accepted_version: 1,
189        maximum_accepted_version: 1,
190    },
191    FamilySpec {
192        family: FormatFamily::Postings,
193        current_version: 1,
194        minimum_accepted_version: 1,
195        maximum_accepted_version: 1,
196    },
197    FamilySpec {
198        family: FormatFamily::ChecksumTable,
199        current_version: 1,
200        minimum_accepted_version: 1,
201        maximum_accepted_version: 1,
202    },
203    FamilySpec {
204        family: FormatFamily::Manifest,
205        current_version: 2,
206        minimum_accepted_version: 2,
207        maximum_accepted_version: 2,
208    },
209    FamilySpec {
210        family: FormatFamily::Wal,
211        current_version: 1,
212        minimum_accepted_version: 1,
213        maximum_accepted_version: 1,
214    },
215    FamilySpec {
216        family: FormatFamily::GraphNodeBlocks,
217        current_version: 1,
218        minimum_accepted_version: 1,
219        maximum_accepted_version: 1,
220    },
221    FamilySpec {
222        family: FormatFamily::DocumentVersions,
223        current_version: 1,
224        minimum_accepted_version: 1,
225        maximum_accepted_version: 1,
226    },
227    FamilySpec {
228        family: FormatFamily::StoredMetadata,
229        current_version: 1,
230        minimum_accepted_version: 1,
231        maximum_accepted_version: 1,
232    },
233    FamilySpec {
234        family: FormatFamily::PurgeIntent,
235        current_version: 1,
236        minimum_accepted_version: 1,
237        maximum_accepted_version: 1,
238    },
239    FamilySpec {
240        family: FormatFamily::StoredText,
241        current_version: 1,
242        minimum_accepted_version: 1,
243        maximum_accepted_version: 1,
244    },
245    FamilySpec {
246        family: FormatFamily::NativeGraphObject,
247        current_version: 1,
248        minimum_accepted_version: 1,
249        maximum_accepted_version: 1,
250    },
251    FamilySpec {
252        family: FormatFamily::NativeGraphRoot,
253        current_version: 1,
254        minimum_accepted_version: 1,
255        maximum_accepted_version: 1,
256    },
257    FamilySpec {
258        family: FormatFamily::NativeGraphWal,
259        current_version: 1,
260        minimum_accepted_version: 1,
261        maximum_accepted_version: 1,
262    },
263];
264
265impl FormatRegistry {
266    /// Returns every registered family in permanent identifier order.
267    #[must_use]
268    pub const fn families() -> &'static [FamilySpec] {
269        &FAMILIES
270    }
271
272    /// Resolves and validates one family version.
273    pub fn require(family: u16, version: u16) -> Result<&'static FamilySpec, RegistryError> {
274        let spec = FAMILIES
275            .iter()
276            .find(|candidate| candidate.family.id() == family)
277            .ok_or(RegistryError::UnknownFamily(family))?;
278        if version < spec.minimum_accepted_version || version > spec.maximum_accepted_version {
279            return Err(RegistryError::UnsupportedVersion {
280                family,
281                version,
282                minimum: spec.minimum_accepted_version,
283                maximum: spec.maximum_accepted_version,
284            });
285        }
286        Ok(spec)
287    }
288
289    /// Rejects retired ids 3 and 5 and validates every live v1 scheme id.
290    pub const fn require_scheme(scheme: u16) -> Result<(), RegistryError> {
291        match scheme {
292            0 | 1 | 2 | 4 => Ok(()),
293            3 | 5 => Err(RegistryError::RetiredScheme(scheme)),
294            _ => Err(RegistryError::UnknownScheme(scheme)),
295        }
296    }
297}