overlay-map

Crates.iooverlay-map
lib.rsoverlay-map
version0.2.2
created_at2025-04-04 22:36:06.092241+00
updated_at2025-04-07 16:59:55.84478+00
descriptionA two-layered map data structure for Rust that tracks current and previous values for each key โ€” with zero-clone, in-place state transitions.
homepagehttps://github.com/jameslkingsley/overlay-map
repositoryhttps://github.com/jameslkingsley/overlay-map
max_upload_size
id1620886
size191,097
James Kingsley (jameslkingsley)

documentation

https://docs.rs/overlay-map

README

overlay-map

overlay-map is a two-layered map data structure for Rust that tracks current and previous values for each key โ€” with zero-clone, in-place state transitions.

It provides OverlayMap<K, V>, a map where each value is an Overlay<V>: a compact two-slot container that allows pushing, swapping, and pulling values without cloning or heap allocation.

๐Ÿ“ฆ Features

  • โœ… In-place, zero-cost value updates
  • โœ… Foreground and background storage per key
  • โœ… On push, the current foreground is moved to background
  • โœ… No heap allocation or cloning for updates
  • โœ… Conditional updates (push_if)
  • โœ… Automatic removal when entries become empty
  • โœ… Overlay<T> usable independently from the map

๐Ÿง  Core types

OverlayMap<K, V>

A map-like wrapper for managing per-key two-layered state.

Overlay<T>

A standalone container that tracks two versions of a value:

  • fg โ†’ the current value
  • bg โ†’ the previous value (optional)

Uses zero-copy, branchless slot flipping via raw memory and bitflags.

๐Ÿš€ Example: Revolving Door of Values

use overlay_map::Overlay;

fn main() {
    let mut door = Overlay::new_fg("Alice");
    println!("Present: {:?}, {:?}", door.fg(), door.bg());

    for name in ["Bob", "Carol", "Dave", "Eve"] {
        if let Some(evicted) = door.swap(name) {
            println!("{evicted} left");
        }

        println!("Present: {:?}, {:?}", door.bg(), door.fg());
    }

    while let Some(pulled) = door.pull() {
        println!("{pulled} left");
    }

    println!("Present: {:?}, {:?}", door.bg(), door.fg());
}

๐Ÿ”ฌ Internal Design

  • Overlay<T> uses [MaybeUninit<T>; 2] with a compact bitflag for presence and slot state.
  • No heap allocation, no Option<T>, no clone required.
  • Operations like push, pull, swap are in-place and branch-minimal.
  • Designed for high-throughput, zero-cost data flow and state management.

๐Ÿง  Why use this?

overlay-map is ideal for:

  • Managing current vs previous state without full history
  • Speculative updates, rollback systems, or caching layers
  • Config overlays, merging, and snapshotting
  • Avoiding unnecessary cloning, allocation, and indirection in hot code paths

๐Ÿงช Performance: Overlay<T> vs Option<(T, Option<T>)>

These benchmarks measure the performance of the push operation in both the Overlay<T> and a conventional tuple-based implementation. Recorded on a MacBook Air M4.

๐Ÿ“Š Overlay Implementation

Overlay PDF Overlay Regression

๐Ÿ“Š Tuple Implementation

Tuple PDF Tuple Regression

๐Ÿ“Š Interpretation

  • Overlay:
    • Operates near L1 cache speeds (sub-100ps per op).
    • Compact, branchless bitfield logic leads to extremely low overhead.
  • Tuple:
    • Slower and more predictable due to enum tagging and control-flow overhead.
    • Useful baseline, but significantly outperformed by Overlay.

These graphs were generated using Criterion.rs and represent measured runtime distribution and scaling with iteration count.

๐Ÿ“š Documentation

๐Ÿ”’ License

MIT

โœจ Contributing

Contributions, bug reports, and feature ideas welcome.

Commit count: 23

cargo fmt