I made a generational arena that lets you pick the key size, the key layout and the storage of the arena.
You can pick the integer types for the index and the generation, and whether a key stores them as two fields or packs them into one integer.
With packing, a key can be 4 bytes, with 24 bits of index and 8 of generation, and Option<Key> is the same size as Key due to the power of NonZero ![]()
Slots of this arena can't only live inside a vec Vec. You can change it to something like an ArrayVec or SmallVec with some feature flags enabled if you want to avoid heap allocs
Here is an example of how you could customize it:
(Note: How configuring is done may change in the future. crates.io would have an up to date example)
use arrayvec::ArrayVec;
use gen_map::{Config, GenMap, Packed};
struct Small;
impl Config for Small {
type Idx = u32;
type Gen = u8;
// The index works with 24 bits and the generation works with 8.
type Layout = Packed<u32, 8>;
// This needs the `arrayvec` feature, and never allocates anything.
type Storage<S> = ArrayVec<S, 256>;
const WRAP_ON_OVERFLOW: bool = false;
}
let mut map = GenMap::<u64, Small>::new_with_config();
let key = map.insert(7);
assert_eq!(core::mem::size_of_val(&key), 4);
There's also some additional methods like retire that lets you manually retire a slot, even if WRAP_ON_OVERFLOW is true, as well as methods to get elements by the index only, instead of requiring the key.
I pretty much made this library while always thinking: "What if I wanted to do x and y with the generational arena without having to write workarounds"
I would love some feedback on the API, and any recommendations on what I could add!
PS: This was AI-assisted. I designed the API and made the design decisions, and used an AI assistant for parts of the implementation, tests and docs, which are all thoroughly reviewed.