Skip to content

feat(mmap): Introduce zero-copy memory-mapped file decompression - #349

Draft
hellobertrand wants to merge 4 commits into
mainfrom
feat/mmap-inplace-decode
Draft

feat(mmap): Introduce zero-copy memory-mapped file decompression#349
hellobertrand wants to merge 4 commits into
mainfrom
feat/mmap-inplace-decode

Conversation

@hellobertrand

@hellobertrand hellobertrand commented Jul 30, 2026

Copy link
Copy Markdown
Owner

This change introduces a new zxc_mmap.h API for decompressing zxc archives directly from files into memory-mapped regions. This eliminates input staging buffers and separate output allocations, leading to:

  • Zero-copy reads of compressed data on POSIX systems.
  • Single-copy reads on Windows (archive copied once to the region).
  • Significant reductions in peak Resident Set Size (RSS), measured at 25 to 50%.

The API also includes functions to map files read-only, allowing existing buffer APIs to consume on-disk archives without an input copy. A new ZXC_ERROR_UNSUPPORTED error code is added for platforms where memory mapping is unavailable.

@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.30508% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/lib/zxc_common.c 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Comment thread tests/test_mmap.c Dismissed
@hellobertrand hellobertrand added the enhancement New feature or request label Jul 30, 2026
@hellobertrand
hellobertrand force-pushed the feat/mmap-inplace-decode branch 2 times, most recently from 48c85f1 to 509c345 Compare July 31, 2026 16:36
This change introduces a new `zxc_mmap.h` API for decompressing ZXC archives directly from files into memory-mapped regions. This eliminates input staging buffers and separate output allocations, leading to:
- Zero-copy reads of compressed data on POSIX systems.
- Single-copy reads on Windows (archive copied once to the region).
- Significant reductions in peak Resident Set Size (RSS), measured at 24-49%.

The API also includes functions to map files read-only, allowing existing buffer APIs to consume on-disk archives without an input copy. A new `ZXC_ERROR_UNSUPPORTED` error code is added for platforms where memory mapping is unavailable.
Introduce true zero-copy memory-mapped decompression for Windows 10 1803 (and Server 2019) and later, leveraging placeholder mappings via `VirtualAlloc2` and `MapViewOfFile3`.

These APIs are resolved dynamically at runtime, allowing the library to gracefully fall back to a single archive copy on older Windows versions, maintaining compatibility without increasing minimum OS
requirements.

Add `zxc_mmap_is_zerocopy()` to report whether the zero-copy route was successfully employed, aiding in deployment observability.
A seekable archive decodes through the mapped path like any other -- the seek
table sits behind the EOF block, so the decoder skips it -- but nothing
exercised that, and the in-place bound had to reserve the table first (see the
preceding fix). mmap_case() gains block_size + seekable parameters, with the
biting shape as the regression: 8 MiB of incompressible data in 4 KiB blocks,
where the seek table used to exceed the whole margin.

For random access the mapped API is not the answer: zxc_decompress_mmap decodes
a whole frame. zxc_mmap_open composes with the seekable API instead, as a
zero-copy backend for zxc_reader_t whose read_at is a memcpy out of the mapping
-- no read() syscall per block, and reentrant, so zxc_seekable_decompress_range_mt
is legal on it. Documented in API.md section 7b, with a pointer to it from the
seekable-reader example in EXAMPLES.md.
Enhance clarity and maintainability of the memory-mapped decompression subsystem by adding Doxygen-style docstrings to static functions and refactoring platform-specific includes.
@hellobertrand
hellobertrand force-pushed the feat/mmap-inplace-decode branch from 509c345 to 4c890dc Compare August 12, 2026 19:43
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants