memmap3
Safe memory-mapped I/O with zero-copy persistent data structures.
memmap3 is a complete drop-in replacement for memmap2 that adds a huge additional list of 'safe' features. All memmap2 functionality is available, plus powerful new APIs that eliminate unsafe code while providing automatic persistence.
🎯 Core Features Summary
- 🔄 Auto-Persistence: Changes persist automatically via memory mapping
- 🔒 Zero Unsafe: Safe Rust APIs for all operations
- ⚡ Thread-Safe: Atomic fields work across processes
- 🎭 Convenience Operators:
<<for intuitive data manipulation - 📏 Fixed-Size + Unlimited: Fixed layouts + segmented growth when needed
- 🧩 Rich Type System: Primitives, atomics, strings, collections, nested structs
- 📊 Multidimensional: N-dimensional arrays for join-like operations
- 🔌 Drop-in Compatible: All memmap2 code works unchanged
Quick Start
Add to your Cargo.toml:
[]
= "0.1"
Create persistent data structures:
use *;
Key Features
🔒 Safe API
- Zero unsafe code required in user applications
- Compile-time validation through
#[mmap_struct]macro - Runtime bounds checking for all operations
- UTF-8 validation for string operations
⚡ High Performance
- Zero-copy access to persistent data
- OS-level caching through memory mapping
- Atomic operations for thread-safe access
- Minimal overhead with direct memory access
🧩 Drop-in Compatibility
// Just change your import:
use ; // From this
use ; // To this
// All existing memmap2 code works unchanged!
🔧 The #[mmap_struct] Macro
Transform regular Rust structs into persistent, memory-mapped types:
use *;
🎭 Convenience Operators
Smooth, intuitive syntax for common operations:
// String assignment
&mut my_string << "Hello";
// Vector append
&mut my_vec << item;
// HashMap insertion
&mut my_map << ;
// HashMap key assignment using macro
hashmap_index!;
// Segmented append
&mut my_segmented << item;
📊 Complete Type System
Primitive Types (Native Support)
- Integers: u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize
- Floats: f32, f64
- Bool: bool
- Char: char (stored as u32)
- C-style Enums: Any enum with
#[repr(C)]
Atomic Types (#[mmap(atomic)])
Transform any primitive to thread-safe atomic:
u64→MmapAtomicU64(fetch_add, compare_exchange, etc.)bool→MmapAtomicBool(load, store, etc.)- Plus all integer types + usize/isize
String Types
- Auto-detected:
[u8; N]→MmapString<N>(default behavior) - Explicit:
#[mmap(string)]to force string behavior - Raw binary:
#[mmap(raw)]to keep as byte array
Collection Types
- Vectors:
#[mmap(vec)]transforms[T; N]→MmapVec<T, N> - String Arrays:
#[mmap(string_array)]transforms[[u8; LEN]; N]→MmapStringArray<N, LEN> - Hash Maps:
MmapHashMap<K, V>for key-value storage
Advanced Types
- Segmented:
#[mmap(segmented)]for unlimited growth (breaks fixed-size constraint) - Nested Structs: Full support for complex nested structures
- Multidimensional Arrays:
[[[u8; X]; Y]; Z]for N-dimensional data - Serde Integration: Store any
Serialize/Deserializetype
🔗 Multidimensional & Join-like Operations
Create sophisticated data structures for complex queries:
use *;
🏗️ Fixed-Size Constraint + Segmented Growth
- Most types: Fixed size at compile time for predictable layout
- Exception:
#[mmap(segmented)]allows unlimited growth - Benefit: Known memory layout enables direct pointer arithmetic
⚙️ How Auto-Persistence Works
- Memory Mapping: File mapped into process memory
- Direct Access: Struct fields map directly to file bytes
- OS Sync: Operating system handles sync to disk
- Cross-Process: Multiple processes can share same file safely
Core Types
MmapStruct
Safe wrapper for memory-mapped structs with automatic file management:
use *;
let mut game = create?;
game.level = 5;
game.score = 12345;
&mut game.player_name << "Player1";
Atomic Fields
Thread-safe operations across processes:
use *;
let metrics = create?;
metrics.requests.fetch_add;
Collections
Persistent data structures with dynamic sizing:
use *;
// Persistent hash map
let mut cache = create?;
cache.insert?;
// Multiple assignment syntaxes available:
&mut cache << ; // Tuple insertion
hashmap_index!; // Index-style assignment
cache.set?; // Direct set method
// Persistent vector
let mut log = new;
log.push; // timestamp
// Persistent string
let mut name = new;
&mut name << "Alice";
Supported Types
Primitive Types (no attribute needed)
- Integers: u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize
- Floats: f32, f64
- Bool: bool
- Char: char (stored as u32)
- C-style Enums: Any enum with
#[repr(C)]
Transformed Types (via attributes)
Atomic Types (#[mmap(atomic)])
Transforms regular types to atomic equivalents for thread-safe access:
u8→MmapAtomicU8,u16→MmapAtomicU16, etc.bool→MmapAtomicBool
Strings (#[mmap(string)])
Transforms byte arrays to UTF-8 strings with helper methods:
[u8; N]→MmapString<N>- Provides
.set(),<<operator,.as_str(),.clear()
Vectors (#[mmap(vec)])
Transforms arrays to fixed-capacity vectors:
[T; N]→MmapVec<T, N>- Provides
.push(),.pop(),.len(),.iter(), indexing
String Arrays (#[mmap(string_array)])
Transforms 2D byte arrays to arrays of strings:
[[u8; LEN]; N]→MmapStringArray<N, LEN>- Provides indexed access to multiple strings
Running Examples
See the examples/ directory for complete working examples:
Examples
Simple Configuration Storage
use *;
let mut config = create?;
config.max_connections = 1000;
config.timeout_ms = 5000;
&mut config.server_name << "production-server";
// Configuration persists across application restarts
Inter-Process Communication
use *;
use Ordering;
// Process A
let shared = create?;
shared.message_count.store;
// Process B can read the same data
let shared = open?;
let count = shared.message_count.load;
println!; // Prints: Messages: 42
Persistent Analytics
use *;
use Ordering;
let analytics = create?;
// Record events
analytics.page_views.fetch_add;
analytics.unique_visitors.fetch_add;
// Calculate conversion rate (example: 2.5% as 250 basis points)
let rate = / page_views;
analytics.conversion_rate.store;
How It Works
The #[mmap_struct] attribute macro:
- Automatically adds
#[repr(C)]for predictable memory layout - Transforms annotated fields to thread-safe types
- Generates trait implementations for memory mapping
- Handles file creation, opening, and validation
Thread Safety
- Regular fields: Single writer, multiple readers (protected by OS page cache)
- Atomic fields: Multiple concurrent writers and readers
- String fields: Single writer with UTF-8 validation
Using with Arc for Shared Access
You can wrap MmapStruct in Arc for safe sharing across threads:
use *;
use Arc;
use Ordering;
// Single-threaded use
let mut data = create?;
data.port = 8080; // Can modify all fields
// Multi-threaded use with Arc
let shared = new;
// Clone for each thread
let thread_data = shared.clone;
spawn;
Access Patterns:
- No Arc: Full read/write access to all fields (single-threaded)
- With Arc: Atomic fields writable, regular fields read-only (multi-threaded)
- With Arc<Mutex<...>>: If you need to modify regular fields from multiple threads
String Handling
Automatic string operations for byte arrays:
use *;
let mut user = create?;
user.id = 12345;
// Write strings using << operator
&mut user.name << "Alice Smith";
&mut user.email << "alice@example.com";
// Read strings back
println!;
Feature Flags
Enable additional functionality:
[]
= { = "0.1", = ["serde"] }
serde- Serialize/deserialize support for complex types
Documentation
- API Reference - Complete API documentation
- Cookbook Examples - Real-world usage patterns
- Migration Guide - Upgrading from memmap2
Use Cases
- Inter-process communication - Shared configuration and state
- Event logging - High-performance ring buffers
- ML model weights - Instant loading of large models
- Game save states - Fast persistence and loading
- Database indexes - Memory-mapped B-trees
Performance
memmap3 provides zero-copy access with minimal overhead:
- Direct memory access - No serialization/deserialization
- OS page cache integration - Automatic memory management
- Lazy loading - Only accessed pages are loaded
- Cross-process sharing - Efficient memory usage
Safety Guarantees
Multiple layers of safety validation:
- Compile-time validation -
#[mmap_struct]macro checks - Runtime bounds checking - All array/collection access
- Memory layout verification - Struct compatibility validation
- UTF-8 validation - String operation safety
- Atomic operation safety - Cross-process synchronization
License
This project is licensed under the MIT OR Apache-2.0 license.
Contributing
Contributions are welcome! Please see our GitHub repository for guidelines.