memsnap
A library for creating memory snapshots and views with copy-on-write semantics.
Overview
memsnap has two main components: Snapshot and View. The Snapshot represents an opaque memory region that can be created from various sources (like files or byte slices), while the View provides a way to access and manipulate that memory region with different semantics.
memsnap allows you to:
- Create memory snapshots from files, byte slices, or zero-initialized memory
- Create copy-on-write views that allow you to modify memory without affecting the original data
- Create mutable views for direct modification of a snapshot
Currently memsnap uses mmap on Unix and MapViewOfFile3 on Windows.
Usage
Basic Example
use memsnap::Snapshot;
fn main() -> std::io::Result<()> {
let snapshot = Snapshot::from_slice(b"Hello, World!")?;
let mut cow_view = snapshot.view()?;
cow_view[0] = b'h';
assert_eq!(&cow_view[..5], b"hello");
let original_view = snapshot.view()?;
assert_eq!(&original_view[..5], b"Hello");
Ok(())
}
Mutable Views
use memsnap::Snapshot;
fn main() -> std::io::Result<()> {
let mut snapshot = Snapshot::from_slice(b"Hello, World!")?;
{
let mut mut_view = snapshot.view_mut()?;
mut_view[0] = b'J';
mut_view[7] = b'R';
}
let view = snapshot.view()?;
assert_eq!(&view[..13], b"Jello, Rorld!");
Ok(())
}
Working with Files
use memsnap::Snapshot;
use std::fs::File;
use std::io::Write as _;
use std::env::temp_dir;
fn main() -> std::io::Result<()> {
let root = tempfile::tempdir()?;
let mut file = File::create_new(root.path().join("example.txt"))?;
file.write_all(b"Hello, File!")?;
let snapshot = Snapshot::from_file(file)?;
let view = snapshot.view()?;
assert_eq!(&view[..12], b"Hello, File!");
Ok(())
}
Arc-based Views for 'static Lifetime
use memsnap::Snapshot;
use std::sync::Arc;
fn main() -> std::io::Result<()> {
let snapshot = Arc::new(Snapshot::from_slice(b"Shared data")?);
let view = snapshot.view_arc()?;
std::thread::spawn(move || {
println!("Data from thread: {:?}", &view[..11]);
}).join().unwrap();
Ok(())
}
Taking new Snapshots
use memsnap::Snapshot;
fn main() -> std::io::Result<()> {
let mut snapshot1 = Snapshot::from_slice(b"Original")?;
let mut view1 = snapshot1.view_mut()?;
view1[0] = b'M';
let snapshot2 = view1.take_snapshot()?;
view1[1] = b'X';
let view2 = snapshot2.view()?;
assert_eq!(&view2[..8], b"Mriginal");
assert_eq!(&view1[..8], b"MXiginal");
Ok(())
}