Skip to main content

qualia_core_db/
archive.rs

1#[cfg(not(target_arch = "wasm32"))]
2use memmap2::MmapOptions;
3#[cfg(not(target_arch = "wasm32"))]
4use std::fs::File;
5#[cfg(not(target_arch = "wasm32"))]
6use std::io;
7#[cfg(not(target_arch = "wasm32"))]
8use std::io::{Cursor, Read};
9#[cfg(not(target_arch = "wasm32"))]
10use std::path::Path;
11
12/// Magic number for `.q42` luminary archive.
13pub const Q42_MAGIC: [u8; 4] = [0x51, 0x34, 0x32, 0x00]; // "Q42\0"
14
15/// Fixed-size Preamble (64 bytes) memory-mapped directly.
16#[repr(C, packed)]
17#[derive(Debug, Clone, Copy)]
18pub struct Q42Preamble {
19    pub magic: [u8; 4],
20    pub version: u16,
21    pub global_flags: u16,
22
23    // Dictionary Manifest (4 pointers x 4 bytes)
24    // Each pointer is a 2-byte offset (relative to 0x40) and 2-byte size
25    pub dict_manifest_standard: [u16; 2],
26    pub dict_manifest_permissive: [u16; 2],
27    pub dict_manifest_bilateral: [u16; 2],
28    pub dict_manifest_spatiotemporal: [u16; 2],
29
30    // Tier Index Manifest (4 pointers x 8 bytes)
31    // Each pointer is a 4-byte physical offset and 4-byte size indicating where the Jump Tables begin
32    pub index_manifest_standard: [u32; 2],
33    pub index_manifest_permissive: [u32; 2],
34    pub index_manifest_bilateral: [u32; 2],
35    pub index_manifest_spatiotemporal: [u32; 2],
36
37    pub eof_marker: u64,
38}
39
40/// Fixed-size Jump Table entry (12 bytes).
41#[repr(C, packed)]
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
43pub struct Q42JumpEntry {
44    pub virtual_chunk_id: u32,
45    pub physical_offset_low: u32,
46    pub physical_offset_high: u16, // 6-byte offset total
47    pub frame_size: u16,
48}
49
50impl Q42JumpEntry {
51    pub fn physical_offset(&self) -> u64 {
52        (self.physical_offset_low as u64) | ((self.physical_offset_high as u64) << 32)
53    }
54}
55
56/// The main Q42 Archive reader utilizing memory-mapping and zero-deserialization structs.
57#[cfg(not(target_arch = "wasm32"))]
58pub struct Q42Archive {
59    mmap: memmap2::Mmap,
60}
61
62#[cfg(not(target_arch = "wasm32"))]
63impl Q42Archive {
64    /// Opens and memory-maps a `.q42` file, instantly verifying the magic preamble.
65    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<Self> {
66        let file = File::open(path)?;
67        let mmap = unsafe { MmapOptions::new().map(&file)? };
68
69        if mmap.len() < 64 {
70            return Err(io::Error::new(
71                io::ErrorKind::UnexpectedEof,
72                "File too small to contain Q42 Preamble",
73            ));
74        }
75
76        let archive = Self { mmap };
77        let preamble = archive.preamble();
78
79        if preamble.magic != Q42_MAGIC {
80            return Err(io::Error::new(
81                io::ErrorKind::InvalidData,
82                "Invalid Q42 Magic Number",
83            ));
84        }
85
86        Ok(archive)
87    }
88
89    /// Casts the first 64 bytes into the `Q42Preamble` instantly.
90    pub fn preamble(&self) -> &Q42Preamble {
91        unsafe { &*(self.mmap.as_ptr() as *const Q42Preamble) }
92    }
93
94    /// Reads a specific jump table from the mapped memory.
95    pub fn read_jump_table(&self, offset: u32, size_bytes: u32) -> &[Q42JumpEntry] {
96        let start = offset as usize;
97        let end = start + size_bytes as usize;
98        let count = size_bytes as usize / std::mem::size_of::<Q42JumpEntry>();
99
100        unsafe {
101            std::slice::from_raw_parts(self.mmap[start..end].as_ptr() as *const Q42JumpEntry, count)
102        }
103    }
104
105    /// Reads a dictionary from the dictionary sector.
106    pub fn read_dictionary(&self, offset: u16, size_bytes: u16) -> &[u8] {
107        let start = 0x40 + offset as usize;
108        let end = start + size_bytes as usize;
109        &self.mmap[start..end]
110    }
111
112    /// Fetches and decompresses a specific 128KB frame dynamically using the embedded Zstd dictionary.
113    pub fn decompress_frame(&self, entry: &Q42JumpEntry, dict: &[u8]) -> io::Result<Vec<u8>> {
114        let start = entry.physical_offset() as usize;
115        let end = start + entry.frame_size as usize;
116        let compressed_data = &self.mmap[start..end];
117
118        let mut decoder =
119            zstd::stream::Decoder::with_dictionary(Cursor::new(compressed_data), dict)?;
120        let mut output = Vec::with_capacity(128 * 1024);
121        decoder.read_to_end(&mut output)?;
122
123        Ok(output)
124    }
125}
126
127#[cfg(test)]
128mod tests {
129    use super::*;
130    use std::io::Write;
131    use tempfile::NamedTempFile;
132
133    #[test]
134    fn test_zero_deserialization_header_alignment() {
135        assert_eq!(std::mem::size_of::<Q42Preamble>(), 64);
136        assert_eq!(std::mem::size_of::<Q42JumpEntry>(), 12);
137    }
138
139    #[test]
140    fn test_q42_archive_mapping() {
141        let mut file = NamedTempFile::new().unwrap();
142
143        let preamble = Q42Preamble {
144            magic: Q42_MAGIC,
145            version: 1,
146            global_flags: 0,
147            dict_manifest_standard: [0, 0],
148            dict_manifest_permissive: [0, 0],
149            dict_manifest_bilateral: [0, 0],
150            dict_manifest_spatiotemporal: [0, 0],
151            index_manifest_standard: [0, 0],
152            index_manifest_permissive: [0, 0],
153            index_manifest_bilateral: [0, 0],
154            index_manifest_spatiotemporal: [0, 0],
155            eof_marker: 64,
156        };
157
158        unsafe {
159            let bytes = std::slice::from_raw_parts(&preamble as *const _ as *const u8, 64);
160            file.write_all(bytes).unwrap();
161        }
162
163        let archive = Q42Archive::open(file.path()).unwrap();
164        let mapped_preamble = archive.preamble();
165
166        let magic = mapped_preamble.magic;
167        let version = mapped_preamble.version;
168        let eof = mapped_preamble.eof_marker;
169
170        assert_eq!(magic, Q42_MAGIC);
171        assert_eq!(version, 1);
172        assert_eq!(eof, 64);
173    }
174}