#slab #pool #queue #linked-list #deque #allocation #operation #element

no-std slabigator

A fixed-capacity linked list with stable element addressing and no dynamic allocations

13 releases

new 0.9.5 May 15, 2025
0.9.4 May 12, 2025
0.9.3 Mar 5, 2025
0.9.2 Mar 17, 2024
0.1.4 Jun 30, 2022

#58 in Memory management

Download history 562/week @ 2025-01-26 524/week @ 2025-02-02 558/week @ 2025-02-09 417/week @ 2025-02-16 249/week @ 2025-02-23 411/week @ 2025-03-02 390/week @ 2025-03-09 272/week @ 2025-03-16 278/week @ 2025-03-23 288/week @ 2025-03-30 340/week @ 2025-04-06 269/week @ 2025-04-13 443/week @ 2025-04-20 611/week @ 2025-04-27 618/week @ 2025-05-04 804/week @ 2025-05-11

2,480 downloads per month
Used in 3 crates

MIT/Apache

44KB
534 lines

CI Crates.io Documentation

Slabigator

A high-performance linked list that doesn't perform dynamic memory allocations after initialization. It allocates all necessary memory upfront with a fixed capacity, making it ideal for performance-critical applications where memory allocation patterns need to be predictable.

Features

Slabigator was designed to do a few things extremely well:

  • Add to the head of the list in O(1) time - Returns a stable slot number for future reference
  • Pop from the tail of the list in O(1) time
  • Delete any element given its slot number in O(1) time
  • Fixed memory allocation - No dynamic allocations after initialization

It's designed to be:

  • Fast: O(1) operations with minimal overhead
  • Predictable: No memory allocations during operations
  • Simple: Small, focused API for specific use cases
  • Maintainable: Small codebase with zero dependencies

Usage

use slabigator::Slab;

// Create a new slab with a capacity of 3 elements
let mut slab = Slab::with_capacity(3).unwrap();

// Add elements to the front - each operation returns a slot number
let slot_a = slab.push_front("a").unwrap();
let slot_b = slab.push_front("b").unwrap();
let slot_c = slab.push_front("c").unwrap();

// Slab is now full (capacity = 3)
assert!(slab.is_full());
assert_eq!(slab.len(), 3);

// Access elements directly by their slots
assert_eq!(slab.get(slot_a).unwrap(), &"a");
assert_eq!(slab.get(slot_b).unwrap(), &"b");
assert_eq!(slab.get(slot_c).unwrap(), &"c");

// Remove an element by its slot
slab.remove(slot_b).unwrap();
assert_eq!(slab.len(), 2);

// Pop elements from the back (FIFO behavior)
assert_eq!(slab.pop_back().unwrap(), "a");
assert_eq!(slab.pop_back().unwrap(), "c");
assert!(slab.is_empty());

When to Use Slabigator

Slabigator is ideal for scenarios where:

  • You need to maintain a list with stable references to elements
  • Memory allocation predictability is critical
  • You need fast (O(1)) operations for all common list operations
  • You know the maximum size of the list in advance
  • You need a simple FIFO queue with the ability to remove arbitrary elements

Common use cases include:

  • Real-time systems where allocation jitter is problematic
  • Memory-constrained environments
  • High-performance queues for task management
  • Cache implementations with fixed capacity
  • Game development for object pools

Cargo Features

Slabigator comes with several feature flags to customize its behavior:

  • releasefast: Assumes that remove() will always be called with a valid index. This saves memory by removing validation checks, but must be used with extreme caution. Disabled by default.
  • slot_u32: Uses u32 as the slot type (default)
  • slot_u64: Uses u64 as the slot type
  • slot_usize: Uses usize as the slot type

Installation

Add this to your Cargo.toml:

[dependencies]
slabigator = "0.9"

Trait Implementations

Slabigator implements several useful Rust traits:

  • Default: Creates a slab with a default capacity of 16
  • FromIterator<T>: Creates a slab from any iterator
  • Extend<T>: Extends a slab with elements from an iterator
  • Index<Slot> and IndexMut<Slot>: Allows direct indexing with [] syntax
  • IntoIterator for &Slab<T>: Enables iteration with for loops

No runtime deps