High-performance cache policies and supporting data structures.
An intrusive list stores prev/next pointers inside the node itself. This makes list operations O(1) without allocating wrapper list nodes.
Used for:
You need:
Node { prev: Option<Handle>, next: Option<Handle>, ... }List { head: Option<Handle>, tail: Option<Handle>, len: usize }Where Handle is one of:
NonNull<Node> (pointer-based)EntryId/usize index into a stable arena/slot vector (recommended)push_front(handle)push_back(handle)remove(handle)move_to_front(handle) (remove + push_front)pop_front() / pop_back()Maintain these at all times:
head.prev == Nonetail.next == Nonen in the list:
n.next = Some(m), then m.prev = Some(n)n.prev = Some(p), then p.next = Some(n)len matches number of nodes reachable from head (debug-only validation is useful)NonNull<Node>)Pros: direct, classic LRU design. Cons: unsafe invariants and lifetime management.
Box, arena allocation).usize/EntryId)Pros: usually safe, cache-friendly, easier to test. Cons: requires a stable slot array.
Vec<NodeSlot>; each node stores prev/next as indices.Index-based is a good “generalized DS” because it composes cleanly with slot-arena.md.
Option<Entry> slots).Vec of nodes without stable slots (reallocation moves nodes; breaks pointer-based lists).