Skip to main content

hexz_core/ops/
inspect.rs

1//! Snapshot inspection without fully opening the file.
2
3use crate::format::header::{CompressionType, Header};
4use crate::format::index::MasterIndex;
5use hexz_common::Result;
6use std::fs::File;
7use std::path::Path;
8
9/// Metadata extracted from a snapshot file.
10pub struct SnapshotInfo {
11    pub version: u32,
12    pub block_size: u32,
13    pub compression: CompressionType,
14    pub encrypted: bool,
15    pub parent_path: Option<String>,
16    pub has_disk: bool,
17    pub has_memory: bool,
18    pub variable_blocks: bool,
19    pub disk_size: u64,
20    pub memory_size: u64,
21    pub file_size: u64,
22    pub index_offset: u64,
23    pub disk_pages: usize,
24    pub memory_pages: usize,
25    pub signature_present: bool,
26    pub dictionary_present: bool,
27    pub metadata_offset: Option<u64>,
28    pub metadata_length: Option<u32>,
29}
30
31impl SnapshotInfo {
32    /// Total uncompressed size (disk + memory).
33    pub fn total_uncompressed(&self) -> u64 {
34        self.disk_size + self.memory_size
35    }
36
37    /// Compression ratio (uncompressed / file size).
38    pub fn compression_ratio(&self) -> f64 {
39        if self.file_size > 0 {
40            self.total_uncompressed() as f64 / self.file_size as f64
41        } else {
42            0.0
43        }
44    }
45}
46
47/// Inspect a snapshot and extract metadata without fully opening it.
48pub fn inspect_snapshot(path: impl AsRef<Path>) -> Result<SnapshotInfo> {
49    let mut f = File::open(path.as_ref())?;
50    let file_size = f.metadata()?.len();
51
52    let header = Header::read_from(&mut f)?;
53    let master = MasterIndex::read_from(&mut f, header.index_offset)?;
54
55    Ok(SnapshotInfo {
56        version: header.version,
57        block_size: header.block_size,
58        compression: header.compression,
59        encrypted: header.encryption.is_some(),
60        parent_path: header.parent_path,
61        has_disk: header.features.has_disk,
62        has_memory: header.features.has_memory,
63        variable_blocks: header.features.variable_blocks,
64        disk_size: master.disk_size,
65        memory_size: master.memory_size,
66        file_size,
67        index_offset: header.index_offset,
68        disk_pages: master.disk_pages.len(),
69        memory_pages: master.memory_pages.len(),
70        signature_present: header.signature_offset.is_some(),
71        dictionary_present: header.dictionary_offset.is_some(),
72        metadata_offset: header.metadata_offset,
73        metadata_length: header.metadata_length,
74    })
75}