pub struct Archive {
pub header: Header,
pub metadata: Option<Vec<u8>>,
/* private fields */
}Expand description
Read-only interface for accessing Hexz archive data.
Archive is the primary API for reading compressed, block-indexed archives.
It handles:
- Logical-to-Physical Mapping: Translates byte offsets to blocks via index pages.
- Compression: Transparent decompression using LZ4 or Zstandard.
- Encryption: Transparent decryption using AES-256-GCM.
- Caching: Two-level caching (L1 decompressed blocks, L2 index pages).
- Thin Archives: Resolves missing blocks from parent archives.
- Prefetching: Asynchronous background loading of sequential blocks.
§Thread Safety
Archive is Send + Sync. All methods are thread-safe and utilize sharded
locks to minimize contention during concurrent reads.
Fields§
§header: HeaderArchive metadata (sizes, compression, encryption settings)
metadata: Option<Vec<u8>>Decoded metadata bytes from the metadata section
Implementations§
Source§impl Archive
impl Archive
Sourcepub fn open(
backend: Arc<dyn StorageBackend>,
encryptor: Option<Box<dyn Encryptor>>,
) -> Result<Arc<Self>>
pub fn open( backend: Arc<dyn StorageBackend>, encryptor: Option<Box<dyn Encryptor>>, ) -> Result<Arc<Self>>
Opens a Hexz archive with default cache settings.
This is the primary constructor for Archive. It:
- Reads and validates the archive header (magic bytes, version)
- Deserializes the master index
- Recursively loads parent archives (for thin archives)
- Initializes block and page caches
§Parameters
backend: Implementation ofStorageBackend(Local file, S3, etc.)encryptor: Optional decryptor (required if archive is encrypted)
§Errors
Error::Io: Backend I/O failure or file not found.Error::Format: Invalid magic bytes or corrupted header.Error::Encryption: Missing or incorrect encryption key.
§Example
let backend = Arc::new(FileBackend::new("data.hxz".as_ref())?);
let archive = Archive::open(backend, None)?;
println!("Main size: {} bytes", archive.size(ArchiveStream::Main));Sourcepub fn open_with_cache(
backend: Arc<dyn StorageBackend>,
encryptor: Option<Box<dyn Encryptor>>,
cache_capacity_bytes: Option<usize>,
prefetch_window_size: Option<u32>,
) -> Result<Arc<Self>>
pub fn open_with_cache( backend: Arc<dyn StorageBackend>, encryptor: Option<Box<dyn Encryptor>>, cache_capacity_bytes: Option<usize>, prefetch_window_size: Option<u32>, ) -> Result<Arc<Self>>
Like open but with custom cache capacity.
Sourcepub fn new(
backend: Arc<dyn StorageBackend>,
compressor: Box<dyn Compressor>,
encryptor: Option<Box<dyn Encryptor>>,
) -> Result<Arc<Self>>
pub fn new( backend: Arc<dyn StorageBackend>, compressor: Box<dyn Compressor>, encryptor: Option<Box<dyn Encryptor>>, ) -> Result<Arc<Self>>
Primary constructor for manual Archive initialization.
This is the primary constructor used by hexz-store to supply a
configured compressor and backend.
Sourcepub fn with_cache(
backend: Arc<dyn StorageBackend>,
compressor: Box<dyn Compressor>,
encryptor: Option<Box<dyn Encryptor>>,
cache_capacity_bytes: Option<usize>,
prefetch_window_size: Option<u32>,
) -> Result<Arc<Self>>
pub fn with_cache( backend: Arc<dyn StorageBackend>, compressor: Box<dyn Compressor>, encryptor: Option<Box<dyn Encryptor>>, cache_capacity_bytes: Option<usize>, prefetch_window_size: Option<u32>, ) -> Result<Arc<Self>>
Opens a Hexz archive with custom cache capacity and prefetching.
Sourcepub fn with_cache_and_loader(
backend: Arc<dyn StorageBackend>,
compressor: Box<dyn Compressor>,
encryptor: Option<Box<dyn Encryptor>>,
cache_capacity_bytes: Option<usize>,
prefetch_window_size: Option<u32>,
parent_loader: Option<&ParentLoader>,
) -> Result<Arc<Self>>
pub fn with_cache_and_loader( backend: Arc<dyn StorageBackend>, compressor: Box<dyn Compressor>, encryptor: Option<Box<dyn Encryptor>>, cache_capacity_bytes: Option<usize>, prefetch_window_size: Option<u32>, parent_loader: Option<&ParentLoader>, ) -> Result<Arc<Self>>
Like with_cache but accepts an optional parent loader.
The parent_loader is used to resolve parent archives for thin archives.
If an archive declares parents but no loader is provided, blocks referring
to parents will return zeros.
Sourcepub const fn size(&self, stream: ArchiveStream) -> u64
pub const fn size(&self, stream: ArchiveStream) -> u64
Returns the logical size of a stream in bytes.
§Parameters
stream: The stream to query (Main or Auxiliary)
§Returns
The uncompressed, logical size of the stream. This is the size you would get if you decompressed all blocks and concatenated them.
§Examples
use hexz_core::{Archive, ArchiveStream};
let disk_bytes = archive.size(ArchiveStream::Main);
let mem_bytes = archive.size(ArchiveStream::Auxiliary);
println!("Main: {} GB", disk_bytes / (1024 * 1024 * 1024));
println!("Auxiliary: {} MB", mem_bytes / (1024 * 1024));Sourcepub fn prefetch_spawn_count(&self) -> u64
pub fn prefetch_spawn_count(&self) -> u64
Returns the total number of prefetch operations spawned since this file was opened. Returns 0 if prefetching is disabled.
Sourcepub fn read_block(
&self,
stream: ArchiveStream,
block_idx: u64,
info: &BlockInfo,
) -> Result<Bytes>
pub fn read_block( &self, stream: ArchiveStream, block_idx: u64, info: &BlockInfo, ) -> Result<Bytes>
Reads a single block from this archive.
Sourcepub fn get_block_by_hash(
&self,
hash: &[u8; 32],
) -> Result<Option<(ArchiveStream, u64, BlockInfo)>>
pub fn get_block_by_hash( &self, hash: &[u8; 32], ) -> Result<Option<(ArchiveStream, u64, BlockInfo)>>
Finds a block in this archive by its hash.
Sourcepub fn iter_block_hashes(&self, stream: ArchiveStream) -> Result<Vec<[u8; 32]>>
pub fn iter_block_hashes(&self, stream: ArchiveStream) -> Result<Vec<[u8; 32]>>
Iterates all non-sparse block hashes for the given stream.
Used by hexz-ops to build a ParentIndex for cross-file deduplication
without requiring access to private fields.
Sourcepub fn get_block_info(
&self,
stream: ArchiveStream,
offset: u64,
) -> Result<Option<(u64, BlockInfo)>>
pub fn get_block_info( &self, stream: ArchiveStream, offset: u64, ) -> Result<Option<(u64, BlockInfo)>>
Returns the block metadata for a given logical offset.
Sourcepub fn read_at(
self: &Arc<Self>,
stream: ArchiveStream,
offset: u64,
len: usize,
) -> Result<Vec<u8>>
pub fn read_at( self: &Arc<Self>, stream: ArchiveStream, offset: u64, len: usize, ) -> Result<Vec<u8>>
Reads data from an archive stream at a given offset.
This is the main read method for random access. It:
- Identifies which blocks overlap the requested range
- Fetches blocks from cache or decompresses from storage
- Handles thin archive fallback to parent
- Assembles the final buffer from block slices
§Parameters
stream: Which stream to read from (Main or Auxiliary)offset: Logical byte offset in the streamlen: Number of bytes to read
§Returns
A Vec<u8> containing the requested data. If the request extends beyond
the end of the stream, it is truncated. If it starts beyond the end,
an empty vector is returned.
§Example
// Read first 512 bytes of main stream
let data = archive.read_at(ArchiveStream::Main, 0, 512)?;Sourcepub fn read_at_into(
self: &Arc<Self>,
stream: ArchiveStream,
offset: u64,
buffer: &mut [u8],
) -> Result<()>
pub fn read_at_into( self: &Arc<Self>, stream: ArchiveStream, offset: u64, buffer: &mut [u8], ) -> Result<()>
Reads into a provided buffer. Unused suffix is zero-filled. Uses parallel decompression when spanning multiple blocks.
Sourcepub fn read_at_into_uninit(
self: &Arc<Self>,
stream: ArchiveStream,
offset: u64,
buffer: &mut [MaybeUninit<u8>],
) -> Result<()>
pub fn read_at_into_uninit( self: &Arc<Self>, stream: ArchiveStream, offset: u64, buffer: &mut [MaybeUninit<u8>], ) -> Result<()>
Writes into uninitialized memory. Unused suffix is zero-filled. Uses parallel decompression when spanning multiple blocks.
On error: The buffer contents are undefined (possibly partially written).
Sourcepub fn read_at_into_uninit_bytes(
self: &Arc<Self>,
stream: ArchiveStream,
offset: u64,
buf: &mut [u8],
) -> Result<()>
pub fn read_at_into_uninit_bytes( self: &Arc<Self>, stream: ArchiveStream, offset: u64, buf: &mut [u8], ) -> Result<()>
Like read_at_into_uninit but accepts &mut [u8]. Use from FFI (e.g. Python).
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Archive
impl !RefUnwindSafe for Archive
impl Send for Archive
impl Sync for Archive
impl Unpin for Archive
impl UnsafeUnpin for Archive
impl !UnwindSafe for Archive
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more