What you get
- Zero-copy reads on every mode.
as_slicereturns aMappedSlice<'_>borrowed directly from the mapping. No allocation. No memcpy. Works on read-only, read-write, and copy-on-write mappings uniformly. - Zero-allocation iteration.
mmap.chunks(N)andmmap.pages()walk the file in fixed strides without ever heap-allocating. A 1 GiB scan at 4 KiB chunks skips 262,144 allocations and half the memory bandwidth of the naive approach. - Aligned atomic views.
atomic_u32/atomic_u64return a wrapper that derefs to&AtomicU64. Multi-threadfetch_addover a memory-mapped counter is one cache-line ping; no cross-process locking required. - Configurable durability.
FlushPolicy::EveryBytes(N),EveryWrites(N),EveryMillis(N),Always, orManual. The accumulator is correctly debited on partial flushes (audit C1) and the millis policy actually runs a background flusher (audit C2). - Thread-safe. Interior mutability via
parking_lot::RwLock. Multiple concurrent readers, one writer at a time. Live atomic views blockresize()until released so memory under your reference cannot move (audit C3). - Cross-platform. Linux, macOS, Windows. Per-platform fast paths (
MS_ASYNCflush on Linux,MADV_HUGEPAGEon huge-page hints,posix_fadvisefor OS-level prefetch). - Opt-in surface. Default features are
advise+iterator. Everything else (async,atomic,cow,locking,watch,hugepages) is off by default to keep compile time tight. - MSRV: 1.75. Pinned and verified in CI.
Quick start
[]
= "0.9"
use MemoryMappedFile;
Open-or-create with one call:
use MemoryMappedFile;
Optional features
| Feature | Description |
|---|---|
async |
Tokio-based async helpers for asynchronous file and memory operations. |
advise |
Memory hinting via madvise/posix_madvise (Unix) or PrefetchVirtualMemory (Windows). |
iterator |
Iterator-based access to memory chunks or pages with zero-copy reads. |
hugepages |
Huge Pages via MAP_HUGETLB (Linux) or FILE_ATTRIBUTE_LARGE_PAGES (Windows); falls back to regular pages. |
cow |
Copy-on-Write mapping mode using private per-process memory views. |
locking |
Page-level memory locking via mlock/munlock (Unix) or VirtualLock (Windows). |
atomic |
Atomic views into memory as aligned u32 / u64 with strict alignment checks. |
watch |
File change notifications via polling fallback (native inotify/kqueue/FSEvents/RDCW planned). |
⚠️ Features are opt-in. Enable only those relevant to your use case to reduce compile time and dependency footprint.
Default features
By default, the following features are enabled:
advise— memory access hinting for performance.iterator— iterator-based chunk/page access.
Installation patterns
Default features:
[]
= "0.9"
Enable async helpers:
[]
= { = "0.9", = ["async"] }
Multiple features:
[]
= { = "0.9", = ["cow", "locking"] }
Minimal — disable defaults, opt into only what you need:
[]
= { = "0.9", = false, = ["locking"] }
Flush Policy
mmap-io supports configurable flush behavior for ReadWrite mappings via FlushPolicy, letting you trade off durability and throughput.
Policy variants:
FlushPolicy::Never/FlushPolicy::Manual— no automatic flushes. Callmmap.flush()when you want durability.FlushPolicy::Always— flush after every write; slowest but most durable.FlushPolicy::EveryBytes(n)— accumulate bytes written acrossupdate_region()calls; flush when at leastnbytes have been written.FlushPolicy::EveryWrites(n)— flush after everynwrites.FlushPolicy::EveryMillis(ms)— automatically flushes pending writes at the specified interval using a background thread.
Builder usage:
use ;
use FlushPolicy;
let mmap = builder
.mode
.size
.flush_policy // flush every 256KB written
.create?;
Manual flush:
use ;
let mmap = create_mmap?;
update_region?;
// ... more batched writes ...
flush?; // ensure durability now
[!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.
Round-trip example
Create a file, write to it, and read back:
use ;
Memory Advise (feature = "advise")
Optimize OS-level memory access patterns:
use ;
Iterator-Based Access (feature = "iterator")
Process files in chunks or pages:
use create_mmap;
Page Pre-warming
Eliminate page-fault latency by pre-warming pages into memory before a critical section:
use ;
Atomic Operations (feature = "atomic")
Lock-free concurrent access at aligned offsets:
use create_mmap;
use Ordering;
Memory Locking (feature = "locking")
Prevent pages from being swapped (requires elevated privileges):
use create_mmap;
File Watching (feature = "watch")
Monitor file changes (currently polling-based; native backends planned):
use ;
Copy-on-Write Mode (feature = "cow")
Private per-process memory views:
use MemoryMappedFile;
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 awaiting update_region_async or flush_async, opening a fresh RO mapping observes the persisted data.
Platform Parity
Flush visibility is guaranteed across operating systems: after calling flush() or flush_range(), a newly opened read-only mapping will observe the persisted bytes on all supported platforms.
- 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 each platform.
Huge Pages (feature = "hugepages")
Best-effort huge page support to reduce TLB misses and improve performance for large mappings.
Linux — multi-tier approach for huge page allocation:
- Tier 1: Optimized mapping with immediate
MADV_HUGEPAGEto encourage kernel huge page allocation. - Tier 2: Standard mapping with
MADV_HUGEPAGEhint for Transparent Huge Pages (THP). - Tier 3: Silent fallback to regular pages if huge pages are unavailable.
Windows — attempts FILE_ATTRIBUTE_LARGE_PAGES. Requires the "Lock Pages in Memory" privilege and system configuration. Falls back to normal pages if unavailable.
Other platforms — no-op.
⚠️
.huge_pages(true)does NOT guarantee huge pages will be used. Actual allocation depends on system configuration, available memory, kernel heuristics, and process privileges. The mapping functions correctly regardless of whether huge pages are actually used.
Builder usage:
use ;
let mmap = builder
.mode
.size // 2MB - typical huge page size
.huge_pages // best-effort optimization
.create?;
Safety Notes
- All operations perform bounds checks.
- Unsafe blocks are limited to mapping calls and documented with SAFETY comments.
- Interior mutability uses
parking_lot::RwLockfor 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. 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.
All unsafe logic is documented in the source and footguns are marked with caution.
Minimum supported Rust version
1.75 — pinned in Cargo.toml and verified by CI.
Further reading
- API Reference — full collection of code examples and usage details.
- Changelog — history of project versions and updates.
License
Licensed under the Apache License, Version 2.0. See LICENSE for the full text.
You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for specific language governing permissions and limitations.