alopex_core/storage/format/
mod.rs1pub mod backpressure;
68pub mod footer;
69pub mod header;
70pub mod ingest;
71pub mod models;
72pub mod reader;
73pub mod section;
74pub mod section_columnar;
75pub mod value_separator;
76#[cfg(not(target_arch = "wasm32"))]
77pub mod writer;
78
79pub use backpressure::{CompactionDebtTracker, WriteThrottleConfig};
80pub use footer::FileFooter;
81pub use header::{FileFlags, FileHeader};
82pub use ingest::{ExternalSectionIngest, KeyRange};
83pub use models::{
84 bincode_config, ColumnDefinition, EphemeralDataGcConfig, IndexDefinition, IntentEntry,
85 IntentSection, IntentType, LockEntry, LockSection, LockType, Metadata, RaftEntryType,
86 RaftLogEntry, RaftLogSection, RangeMetadata, TableSchema, VectorIndexMetadata, VectorMetric,
87};
88#[cfg(not(target_arch = "wasm32"))]
89pub use reader::AlopexFileReader;
90#[cfg(target_arch = "wasm32")]
91pub use reader::{AlopexFileReader, WasmReaderConfig};
92#[cfg(target_arch = "wasm32")]
93pub use reader::{BufferRangeLoader, RangeLoader};
94pub use reader::{FileReader, FileSource, PrefetchFuture};
95pub use section::{SectionEntry, SectionIndex, SectionType};
96#[cfg(not(target_arch = "wasm32"))]
97pub use section_columnar::ColumnarSectionWriter;
98pub use section_columnar::{ColumnarSectionReader, SECTION_TYPE_COLUMNAR};
99pub use value_separator::{LargeValuePointer, ValueRef, ValueSeparationConfig, ValueSeparator};
100#[cfg(not(target_arch = "wasm32"))]
101pub use writer::AlopexFileWriter;
102
103use thiserror::Error;
104
105pub const MAGIC: [u8; 4] = *b"ALPX";
107pub const REVERSE_MAGIC: [u8; 4] = *b"XPLA";
109
110pub const HEADER_SIZE: usize = 64;
112pub const FOOTER_SIZE: usize = 64;
114pub const SECTION_ENTRY_SIZE: usize = 40;
116
117pub const VERSION_MAJOR: u16 = 0;
119pub const VERSION_MINOR: u16 = 1;
121pub const VERSION_PATCH: u16 = 0;
123
124#[repr(C)]
126#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
127pub struct FileVersion {
128 pub major: u16,
130 pub minor: u16,
132 pub patch: u16,
134}
135
136impl FileVersion {
137 pub const fn new(major: u16, minor: u16, patch: u16) -> Self {
139 Self {
140 major,
141 minor,
142 patch,
143 }
144 }
145
146 pub const CURRENT: Self = Self::new(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
148}
149
150#[repr(C)]
152#[derive(Debug, Error, PartialEq, Eq)]
153pub enum FormatError {
154 #[error("Invalid magic number: expected ALPX, found {found:?}")]
156 InvalidMagic {
157 found: [u8; 4],
159 },
160
161 #[error(
163 "Incompatible version: file version {file:?} is newer than reader version {reader:?}. Please upgrade Alopex DB."
164 )]
165 IncompatibleVersion {
166 file: FileVersion,
168 reader: FileVersion,
170 },
171
172 #[error("Section {section_id} is corrupted: expected checksum {expected:#x}, found {found:#x}. The section may be damaged.")]
174 CorruptedSection {
175 section_id: u32,
177 expected: u32,
179 found: u32,
181 },
182
183 #[error("File appears to be incomplete (missing or invalid footer). This may indicate a crash during write.")]
185 IncompleteWrite,
186
187 #[error("Key range [{start:?}, {end:?}) overlaps with existing section {section_id}")]
189 KeyRangeOverlap {
190 start: Vec<u8>,
192 end: Vec<u8>,
194 section_id: u32,
196 },
197
198 #[error("Compression algorithm {algorithm} is not supported in this build")]
200 UnsupportedCompression {
201 algorithm: u8,
203 },
204
205 #[error("Compression failed for algorithm {algorithm}")]
207 CompressionFailed {
208 algorithm: u8,
210 },
211
212 #[error("Decompression failed for algorithm {algorithm}")]
214 DecompressionFailed {
215 algorithm: u8,
217 },
218
219 #[error("Checksum algorithm {algorithm} is not supported in this build")]
221 UnsupportedChecksum {
222 algorithm: u8,
224 },
225
226 #[error("Invalid pointer: section_id={section_id}, offset={offset}, length={length}")]
228 InvalidPointer {
229 section_id: u32,
231 offset: u64,
233 length: u64,
235 },
236
237 #[error("Checksum mismatch: expected {expected:#x}, found {found:#x}")]
239 ChecksumMismatch {
240 expected: u64,
242 found: u64,
244 },
245
246 #[error("Invalid key range: start={start:?}, end={end:?}")]
248 InvalidKeyRange {
249 start: Vec<u8>,
251 end: Vec<u8>,
253 },
254
255 #[error("Invalid external section: {message}")]
257 IngestValidationFailed {
258 message: &'static str,
260 },
261}