memsnap

Crates.iomemsnap
lib.rsmemsnap
version0.1.2
created_at2025-08-01 17:19:43.802866+00
updated_at2025-08-02 21:18:52.038389+00
descriptionA library for creating memory snapshots and views with copy-on-write semantics.
homepagehttps://github.com/jprendes/memsnap
repositoryhttps://github.com/jprendes/memsnap
max_upload_size
id1777150
size49,034
Jorge Prendes (jprendes)

documentation

README

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<()> {
    // Create snapshot from a byte slice
    let snapshot = Snapshot::from_slice(b"Hello, World!")?;

    // Create a copy-on-write view
    let mut cow_view = snapshot.view()?;
    
    // Modifications to the view don't affect the original memory
    cow_view[0] = b'h';
    assert_eq!(&cow_view[..5], b"hello");
    
    // Create another view to verify the original is unchanged
    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!")?;
    
    // Create a mutable view
    {
        let mut mut_view = snapshot.view_mut()?;
        mut_view[0] = b'J';
        mut_view[7] = b'R';
    }
    
    // Changes are reflected in the original snapshot
    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<()> {
    // Create a temporary file and write some data to it
    let root = tempfile::tempdir()?;
    let mut file = File::create_new(root.path().join("example.txt"))?;
    file.write_all(b"Hello, File!")?;

    // Create a snapshot from that file
    let snapshot = Snapshot::from_file(file)?;
    
    // Work with the file content
    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")?);
    
    // Create a view with no lifetime restrictions
    let view = snapshot.view_arc()?;
    
    // The view can be sent to other threads
    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()?;

    // Modify the view
    view1[0] = b'M';
    
    // Create a snapshot of the current state
    let snapshot2 = view1.take_snapshot()?;
    
    // Further modifications don't affect the snapshot
    view1[1] = b'X';
    
    let view2 = snapshot2.view()?;
    assert_eq!(&view2[..8], b"Mriginal");
    assert_eq!(&view1[..8], b"MXiginal");
    
    Ok(())
}
Commit count: 0

cargo fmt