Skip to content

jamesgober/arena-lib

Repository files navigation

Rust logo
arena-lib
TYPED MEMORY ARENAS AND SLAB ALLOCATION

crates.io downloads docs.rs CI MSRV

Generational indices, typed arenas, interned strings, bump allocation. Zero unsafe leakage into user code.


Why arena-lib

Allocator-aware Rust normally means juggling three or four crates: one for slab storage, one for handle stability, one for string interning, plus a bump arena for short-lived scratch. arena-lib collects those primitives behind a single, safe, REPS-disciplined surface so you can move fast without paying for it later.

Designed around four guarantees:

  • Typed arenas — one backing allocation per element type, predictable layout, cache-friendly traversal.
  • Generational indices — stable handles that catch use-after-free without reference counting.
  • String interning — O(1) equality and compact storage for repeated identifiers.
  • Bump allocation — short-lived scratch regions that reset in constant time.

Every public path is safe Rust. unsafe lives only in measured, documented internals — never in your call sites.

Status: v1.0.0 — stable. API frozen. Within the 1.x line, only purely additive changes are permitted (new methods on existing types, new variants on the #[non_exhaustive] Error enum). Anything that would break a 1.x caller is out of scope until a hypothetical 2.0.


Quick start

Add the crate to your Cargo.toml:

[dependencies]
arena-lib = "1"

End-to-end use of every primitive:

use arena_lib::prelude::*;

fn main() {
    // Generational arena — stable handles, use-after-free detection.
    let mut arena: Arena<&'static str> = Arena::with_capacity(8);
    let alice = arena.insert("alice");
    let bob = arena.insert("bob");
    assert_eq!(arena.get(alice), Some(&"alice"));

    // String interner — O(1) equality on repeated identifiers.
    let mut interner = Interner::with_capacity(8);
    let id_a = interner.intern("user:alice");
    let id_b = interner.intern("user:alice");
    assert_eq!(id_a, id_b);

    // Bump arena — fast scratch, grows on demand, O(1) reset.
    let bump = Bump::with_capacity(64);
    let scratch = bump.alloc([0_u8; 16]);
    assert_eq!(scratch.len(), 16);

    // Drop arena — same ergonomics but runs destructors on drop.
    let owned = DropArena::<String>::new();
    let s = owned.alloc(String::from("freed when `owned` is dropped"));
    assert!(s.contains("dropped"));

    // Removing a slot invalidates its handle without touching the rest.
    assert_eq!(arena.remove(alice), Some("alice"));
    assert!(arena.get(alice).is_none());
    assert!(arena.get(bob).is_some());
}

See docs/API.md for the full reference, including the planned 1.0 surface.


Standards

  • REPS governs every decision. See REPS.md.
  • MSRV: Rust 1.85.
  • Edition: 2024.
  • Cross-platform: Linux, macOS, Windows.

License

Dual-licensed under either of:

at your option.

COPYRIGHT © 2026 JAMES GOBER.

About

Typed memory arena and slab allocator library. Generational indices, typed arenas (one allocation per type), interned strings, and bump allocation. Zero unsafe leakage into user code. Used in compilers, parsers, query engines, and high-throughput servers.

Topics

Resources

License

Apache-2.0, Unknown licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
Unknown
LICENSE-MIT

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages