array_format/block.rs
1//! Block metadata stored in the footer.
2//!
3//! Each block in the data region has a [`BlockMeta`] entry that records
4//! its physical location in the file and compression information.
5
6use std::ops::Range;
7
8use rkyv::{Archive, Deserialize, Serialize};
9
10use crate::address::BlockId;
11
12/// Identifies which compression codec was used for a block.
13///
14/// `None` means the block is stored uncompressed.
15/// [`Named`](CodecId::Named) allows registering custom codecs by string
16/// identifier without modifying this enum.
17#[derive(Debug, Clone, PartialEq, Archive, Serialize, Deserialize)]
18pub enum CodecId {
19 /// No compression applied.
20 None,
21 /// A named compression codec (e.g. `"zstd"`, `"lz4"`).
22 Named(String),
23}
24
25/// Metadata for a single block in the data region.
26///
27/// Stored in the footer's block table. Describes where to find the
28/// block in the file and how to decompress it.
29#[derive(Debug, Clone, PartialEq, Archive, Serialize, Deserialize)]
30pub struct BlockMeta {
31 /// Block identifier.
32 pub id: BlockId,
33 /// Byte offset of the compressed block within the file.
34 pub file_offset: u64,
35 /// Size of the block as stored on disk (compressed).
36 pub compressed_size: u64,
37 /// Size of the block after decompression.
38 pub uncompressed_size: u64,
39 /// Compression codec used for this block.
40 pub codec: CodecId,
41}
42
43impl BlockMeta {
44 /// Returns the byte range within the file that contains this block.
45 pub fn file_range(&self) -> Range<u64> {
46 self.file_offset..self.file_offset + self.compressed_size
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn file_range_computation() {
56 let meta = BlockMeta {
57 id: BlockId(0),
58 file_offset: 100,
59 compressed_size: 50,
60 uncompressed_size: 200,
61 codec: CodecId::None,
62 };
63 assert_eq!(meta.file_range(), 100..150);
64 }
65
66 #[test]
67 fn named_codec_id() {
68 let codec = CodecId::Named("zstd".into());
69 assert_eq!(codec, CodecId::Named("zstd".into()));
70 assert_ne!(codec, CodecId::None);
71 }
72}