pub struct Registry<Id: Identifier, T> { /* private fields */ }Expand description
A strongly typed vector
§Example
use jstd::Identifier;
use jstd::registry::Registry;
#[derive(Identifier)]
struct ItemId(usize);
let mut reg = Registry::<ItemId, i32>::default();
let id = reg.push(10);
reg[id] += 5;
assert_eq!(reg[id], 15);
assert_eq!(reg.len(), 1);
assert!(!reg.is_empty());Segmented, append-only-stable backing store: element n lives in chunk
k = floor(log2(n + 1)) at offset n + 1 - 2^k, so chunk k holds exactly
2^k elements. Each chunk is allocated once at its full capacity and never
reallocated, so an element’s address is stable for the life of the
registry even as later pushes grow the store (growing appends new chunks;
it never moves existing elements). Growing the outer Vec<Vec<T>> moves the
chunk headers, not their heap buffers. This stability is what lets the
literal/type interners hand out &T references that outlive a mint (see
qcode’s RwLock-wrapped interners). Chunk sizes double, so a small registry
stays cheap (chunks 1, 2, 4, …) and a large one needs few chunks.
The public API is identical to a flat Vec-backed registry: ids are dense
0..len and index in insertion order.
Implementations§
Source§impl<Id: Identifier, T> Registry<Id, T>
impl<Id: Identifier, T> Registry<Id, T>
Sourcepub fn truncate(&mut self, len: usize)
pub fn truncate(&mut self, len: usize)
Drops every element with an id of len or above, keeping the chunks
already allocated so the next pushes reuse them.
The ids below len and their elements’ addresses are unchanged. This
is the one way a registry shrinks: for a construction that appended
elements it then has to take back, and for a scratch store that starts
its ids over.
Sourcepub fn replace(&mut self, id: Id, value: T) -> T
pub fn replace(&mut self, id: Id, value: T) -> T
Replaces the element at id, returning the previous value. The id (and
every element’s stable address) is unchanged. Used to check out an
element — swap in a sentinel, own the original, swap it back later —
without disturbing any other id.
§Panics
Panics if id is out of bounds.
Sourcepub fn get(&self, id: Id) -> Identified<Id, &T>
pub fn get(&self, id: Id) -> Identified<Id, &T>
Sourcepub fn get_mut(&mut self, id: Id) -> Identified<Id, &mut T>
pub fn get_mut(&mut self, id: Id) -> Identified<Id, &mut T>
Sourcepub fn iter(&self) -> Iter<'_, Id, T> ⓘ
pub fn iter(&self) -> Iter<'_, Id, T> ⓘ
Iterates immutably over (id, value) as Identified items.
§Example
use jstd::Identifier;
use jstd::registry::Registry;
#[derive(Identifier)]
struct Id(usize);
let mut reg = Registry::<Id, &str>::default();
reg.push("x");
reg.push("y");
let ids: Vec<usize> = reg.iter().map(|item| usize::from(item.id)).collect();
let vals: Vec<&str> = reg.iter().map(|item| **item).collect();
assert_eq!(ids, vec![0, 1]);
assert_eq!(vals, vec!["x", "y"]);Sourcepub fn iter_mut(&mut self) -> IterMut<'_, Id, T> ⓘ
pub fn iter_mut(&mut self) -> IterMut<'_, Id, T> ⓘ
Iterates mutably over (id, value) as Identified items.
§Example
use jstd::Identifier;
use jstd::registry::Registry;
#[derive(Identifier)]
struct Id(usize);
let mut reg = Registry::<Id, i32>::default();
reg.push(1);
reg.push(2);
for mut item in reg.iter_mut() {
**item += 10;
}
assert_eq!(reg[Id::from(0)], 11);
assert_eq!(reg[Id::from(1)], 12);Sourcepub fn select_mut(&mut self, ids: &[Id]) -> Vec<&mut T>
pub fn select_mut(&mut self, ids: &[Id]) -> Vec<&mut T>
Borrows the elements at ids mutably and disjointly, returned in the same
order as ids.
This is the disjoint-&mut-slice primitive the parallel function-pass
driver uses to hand each worker its own body straight out of the registry,
without the checkout/checkin swap (context-split stage 5b-ii, see
docs/plans/context-split/05b-plan.md §2.2). Because every returned
reference comes from a distinct iter_mut slot, the
borrows are provably non-overlapping and no unsafe is required.
ids must be distinct and in bounds; the returned vector has one
reference per requested id, positionally aligned with ids.
§Panics
Panics if ids contains a duplicate id or an out-of-bounds id.