Capabilities
- Zero-copy reads and efficient writes.
- Read-only and read-write modes.
- Segment-based access (offset + length)
- Thread-safe via interior mutability (parking_lot
RwLock
) - Cross-platform via
memmap2
- Optional async helpers with
Tokio
. - MSRV: 1.76
Optional Features
The following optional Cargo features enable extended functionality for mmap-io
. Enable only what you need to minimize binary size and dependencies.
Feature | Description |
---|---|
async |
Enables Tokio-based async helpers for asynchronous file and memory operations. |
advise |
Enables memory hinting using madvise /posix_madvise (Unix) or Prefetch (Windows). |
iterator |
Provides iterator-based access to memory chunks or pages with zero-copy read access. |
hugepages |
Enables support for Huge Pages via MAP_HUGETLB (Linux) or FILE_ATTRIBUTE_LARGE_PAGES (Windows), reducing TLB misses and improving performance for large memory regions. Requires system configuration and elevated privileges. |
cow |
Enables Copy-on-Write (COW) mapping mode using private memory views (per-process isolation). |
locking |
Enables page-level memory locking via mlock /munlock (Unix) or VirtualLock (Windows). |
atomic |
Exposes atomic views into memory as aligned u32 / u64 , with strict safety guarantees. |
watch |
Enables file change notifications via inotify , kqueue , FSEvents , or ReadDirectoryChangesW . Falls back to polling where unavailable. |
⚠️ Features are opt-in. Enable only those relevant to your use case to reduce compile time and dependency bloat.
Default Features
By default, the following features are enabled:
advise
– Memory access hinting for performanceiterator
– Iterator-based chunk/page access
Installation
Add to your Cargo.toml:
[]
= { = "0.9.3" }
Enable async helpers (
Tokio
) when needed:
[]
= { = "0.9.3", = ["async"] }
Or, enable other features like:
cow
,locking
, oradvise
[]
= { = "0.9.3, features = ["cow", "locking"] }
See full list of Features (shown above).
If you're building for minimal environments or want total control over feature flags, you can disable default features by using default-features = false
(see below).
[]
= { = "0.9.3", = false, = ["locking"] }
Example Usage
use ;
Flush Policy
mmap-io supports configurable flush behavior for ReadWrite mappings via a FlushPolicy
, allowing you to trade off durability and throughput.
Policy variants:
- FlushPolicy::Never / FlushPolicy::Manual: No automatic flushes. Call
mmap.flush()
when you want durability. - FlushPolicy::Always: Flush after every write; slowest but most durable.
- FlushPolicy::EveryBytes(n): Accumulate bytes written across
update_region()
calls; flush when at least n bytes have been written. - FlushPolicy::EveryWrites(n): Flush after every n writes (calls to
update_region()
). - FlushPolicy::EveryMillis(ms): Automatically flushes pending writes at the specified interval using a background thread.
Using the builder to set a policy:
use ;
use FlushPolicy;
let mmap = builder
.mode
.size
.flush_policy // flush every 256KB written
.create?;
Manual flush example:
use ;
let mmap = create_mmap?;
update_region?;
// ... more batched writes ...
flush?; // ensure durability now
Benchmark variants:
- update_only: No flush between writes (Manual policy).
- update_plus_flush: Explicit flush after each write.
- update_threshold: Builder sets threshold to flush periodically to measure batching behavior.
[!NOTE] On some platforms, visibility of writes without explicit flush may still occur due to OS behavior, but durability timing is best-effort without flush.
Create a file, write to it, and read back:
use ;
Memory Advise (feature = "advise")
Optimize memory access patterns:
use ;
Iterator-Based Access (feature = "iterator")
Process files in chunks efficiently:
use create_mmap;
Page Pre-warming (feature = "locking")
Eliminate page fault latency by pre-warming pages into memory.
use ;
Note: The locking feature is currently required for this functionality as it provides the necessary ow-level memory control.
Atomic Operations (feature = "atomic")
Lock-free concurrent access:
use create_mmap;
use Ordering;
Memory Locking (feature = "locking")
Prevent pages from being swapped:
use create_mmap;
File Watching (feature = "watch")
Monitor file changes:
use ;
Copy-on-Write Mode (feature = "cow")
Private memory views:
use ;
Async Operations (feature = "async")
Tokio-based async helpers:
async
Async-Only Flushing
When using async write helpers, mmap-io enforces durability by flushing after each async write. This avoids visibility inconsistencies across platforms when awaiting async tasks.
async
Contract: After await-ing update_region_async or flush_async, reopening a fresh RO mapping observes the persisted data.
Platform Parity
Flush visibility is guaranteed across OSes: after calling flush()
or flush_range()
, a newly opened read-only mapping will observe the persisted bytes on all supported platforms.
Examples:
- Full-file flush: both written regions are visible after
flush()
. - Range flush: only the flushed range is guaranteed visible; a later
flush()
persists remaining regions.
See parity tests in the repository that validate this contract on all platforms.
Huge Pages (feature = "hugepages")
Best-effort huge page support to reduce TLB misses and improve performance for large memory regions:
Linux: Uses a multi-tier approach for optimal huge page allocation::
- Tier 1: Attempts an optimized mapping with immediate
MADV_HUGEPAGE
to encourage kernel huge page allocation. - Tier 2: Falls back to a standard mapping with a
MADV_HUGEPAGE
hint for Transparent Huge Pages (THP). - Tier 3: Silently falls back to regular pages if huge pages are unavailable.
Windows: Attempts to use FILE_ATTRIBUTE_LARGE_PAGES
when creating files. Requires the "Lock Pages in Memory" privilege and system configuration. Falls back to normal pages if unavailable.
Other platforms: No-op (uses normal pages).
⚠️ Important: .huge_pages(true)
does NOT guarantee huge pages will be used. The actual allocation depends on:
- System configuration (huge pages must be enabled)
- Available memory and fragmentation
- Kernel heuristics and available huge page pool
- Process privileges (for explicit huge page allocation)
The mapping will function correctly regardless of whether huge pages are actually used.
Usage via builder:
use ;
let mmap = builder
.mode
.size // 2MB - typical huge page size
.huge_pages // best-effort optimization
.create?;
Important Notes:
- Huge pages are a performance optimization hint, not a guarantee
- The mapping will function correctly regardless of whether huge pages are used
- On Linux, THP provides automatic, transparent fallback to normal pages
- Performance benefits are most noticeable with large, frequently-accessed mappings
Safety Notes
- All operations perform bounds checks.
- Unsafe blocks are limited to mapping calls and documented with SAFETY comments.
- Interior mutability uses
parking_lot::RwLock
for high performance. - Avoid flushing while holding a write guard to prevent deadlocks (drop the guard first).
⚠️ Unsafe Code Disclaimer
This crate uses unsafe
internally to manage raw memory mappings (mmap
, VirtualAlloc
, etc.) across platforms. All public APIs are designed to be memory-safe when used correctly. However:
- You must not modify the file concurrently outside of this process.
- Mapped slices are only valid as long as the underlying file and mapping stay valid.
- Behavior is undefined if you access a truncated or deleted file via a stale mapping.
We document all unsafe logic in the source and mark any footguns with caution.