ranged-mmap-0.3.0 has been yanked.
ranged-mmap
A type-safe, high-performance memory-mapped file library optimized for lock-free concurrent writes to non-overlapping ranges.
Features
- π Zero-Copy Writes: Data is written directly to mapped memory without system calls
- π Lock-Free Concurrency: Multiple threads can write to different file regions simultaneously without locks
- β Type-Safe API: Prevents overlapping writes at compile-time through the type system
- π¦ Reference Counting: Can be cloned and shared among multiple workers
- β‘ High Performance: Optimized for concurrent random writes (see benchmarks)
- π§ Manual Flushing: Fine-grained control over when data is synchronized to disk
- π Runtime Agnostic: Works with any async runtime (tokio, async-std) or without one
- π 4K Alignment: All allocations are automatically aligned to 4K boundaries for optimal I/O performance
- π Dual Allocators: Sequential allocator for single-thread use, wait-free concurrent allocator for multi-thread scenarios
When to Use
Perfect for:
- π Multi-threaded downloaders: Concurrent writes to different file chunks
- π Logging systems: Multiple threads writing to different log regions
- πΎ Database systems: Concurrent updates to different data blocks
- π Large file processing: Parallel processing of different file sections
Not suitable for:
- Files that need dynamic resizing (size must be known at creation)
- Sequential or small file operations (overhead not justified)
- Systems with limited virtual memory
Quick Start
Add to your Cargo.toml:
[]
= "0.3"
Type-Safe Version (Recommended)
The MmapFile API provides compile-time safety guarantees through range allocation:
use ;
use NonZeroU64;
Unsafe Version (Maximum Performance)
For scenarios where you can manually guarantee non-overlapping writes:
use MmapFileInner;
use NonZeroU64;
API Overview
Main Types
MmapFile: Type-safe memory-mapped file with compile-time safetyMmapFileInner: Unsafe high-performance version for manual safety managementRangeAllocator: Trait for range allocatorsallocator::sequential::Allocator: Sequential allocator for single-thread useallocator::concurrent::Allocator: Wait-free concurrent allocator for multi-thread scenariosAllocatedRange: Represents a valid, non-overlapping file rangeWriteReceipt: Proof that a range has been written (enables type-safe flushing)ALIGNMENT: 4K alignment constant (4096 bytes)align_up: Function to align values up to 4K boundary
Core Methods
MmapFile (Type-Safe)
use NonZeroU64;
use ;
// Create file with default sequential allocator
let = create_default?;
// Or specify allocator type explicitly
let = ?;
// Use concurrent allocator for multi-thread allocation
let = ?;
// Allocate ranges (4K aligned, returns Option)
let range = allocator.allocate.unwrap;
// Write to range (returns receipt directly)
let receipt = file.write_range;
// Flush using receipt
file.flush_range;
// Sync all data to disk
unsafe
MmapFileInner (Unsafe)
use NonZeroU64;
// Create file
let file = create?;
// Write at offset (must ensure non-overlapping)
unsafe
// Flush to disk
unsafe
Safety Guarantees
Compile-Time Safety (MmapFile)
The type system ensures:
- β
All ranges are allocated through
RangeAllocator - β Ranges are allocated sequentially/atomically, preventing overlaps
- β All allocations are 4K aligned for optimal I/O performance
- β Data length must match range length
- β
Only written ranges can be flushed (via
WriteReceipt)
Runtime Safety (MmapFileInner)
You must ensure:
- β οΈ Different threads write to non-overlapping memory regions
- β οΈ No reads occur to a region during writes
- β οΈ Proper synchronization if violating the above rules
Performance
This library is optimized for concurrent random write scenarios. Compared to standard tokio::fs::File, it offers:
- Zero system calls for writes: Direct memory modification
- No locks required: True parallel writes to different regions
- Batch flushing: Control when data is synchronized to disk
See benches/concurrent_write.rs for detailed benchmarks.
Advanced Usage
With Concurrent Allocator (Multi-Thread Allocation)
use ;
use NonZeroU64;
use Arc;
With Tokio Runtime
use ;
use NonZeroU64;
use task;
async
Reading Data
use ;
use NonZeroU64;
Opening Existing Files
use ;
use NonZeroU64;
Limitations
- Fixed Size: File size must be specified at creation and cannot be changed
- Virtual Memory: Maximum file size is limited by system virtual memory
- Platform Support: Currently optimized for Unix-like systems and Windows
- No Built-in Locking: Users must manage concurrent access patterns
How It Works
- Memory Mapping: The file is memory-mapped using
memmap2, making it accessible as a continuous memory region - Range Allocation: Allocators provide non-overlapping ranges:
sequential::Allocator: Simple sequential allocation for single-thread useconcurrent::Allocator: Wait-free atomic allocation for multi-thread scenarios
- 4K Alignment: All allocations are aligned to 4K boundaries for optimal I/O performance
- Type Safety:
AllocatedRangecan only be created through the allocator, guaranteeing validity - Lock-Free Writes: Each thread writes to its own
AllocatedRange, avoiding locks - Manual Flushing: Users control when data is synchronized to disk for optimal performance
Comparison
| Feature | ranged-mmap | tokio::fs::File | std::fs::File |
|---|---|---|---|
| Concurrent writes | β Lock-free | β Requires locks | β Requires locks |
| Zero-copy | β Yes | β No | β No |
| Type safety | β Compile-time | β οΈ Runtime | β οΈ Runtime |
| System calls (write) | β Zero | β Per write | β Per write |
| Dynamic size | β Fixed | β Yes | β Yes |
| Async support | β Runtime agnostic | β Tokio only | β No |
Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
License
This project is licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Acknowledgments
Built on top of the excellent memmap2 crate.