o3/depot/raw/mod.rs
1//! Shared storage proofs and operations that consume their exact owning capabilities.
2
3use std::{mem, num::NonZero, slice};
4
5pub use proof::Proof;
6pub(in crate::depot) use proof::{ChainCount, Drain, Numeric, Sealed};
7
8/// Initialized membership retaining its exact source, key, and operation predicate.
9pub(in crate::depot) type Live<S, K, P = ()> = Proof<(S, K), Initialized<P>>;
10
11/// # Safety
12/// The output retains the source's ownership, lifetime, exact slot, state, and plane.
13/// Borrowed outputs cannot create ownership or exclusivity absent from the retained source.
14pub unsafe trait Project<K, P = ()> {
15 type Output;
16 /// # Safety
17 /// This key names an initialized slot in this exact retained source and plane.
18 /// All ownership and state invariants specified by P hold for the retained operation.
19 unsafe fn project(self, key: K) -> Self::Output;
20}
21
22use crate::depot::{
23 arena::linked::{head, slots},
24 capacity,
25 index::{Initialized, Stored, bitmap, set},
26 queue::{
27 indexed::keyed::{self, lanes},
28 links::Index,
29 pool::{Lane, fifo::Fifo},
30 ring, tagged,
31 },
32};
33mod proof;
34
35impl crate::alloc::raw::Empty<capacity::Count> {
36 // SAFETY: Count::EMPTY is zero and its Extent implementation preserves that count.
37 pub const EMPTY: Self = unsafe { Self::assume(capacity::Count::EMPTY) };
38}
39
40/// # Safety
41/// Copies and equal identities retain one direct-address index for life.
42/// `index` is total and numeric, returning normally without callbacks or storage reentry.
43pub unsafe trait Address: Copy + Eq {
44 fn index(self) -> usize;
45}
46
47/// # Safety
48/// Direct-address keys reject `VACANT` and exactly round-trip live identities and indices.
49/// `index` obeys [`Address`]'s projection contract.
50pub unsafe trait Key: Copy + Eq {
51 type Raw: Copy + Eq;
52 const VACANT: Self::Raw;
53 fn index(self) -> usize;
54 fn into_raw(self) -> Self::Raw;
55 /// Reconstructs a key from an identity proven emitted by this key domain.
56 fn from_raw(raw: Stored<Self>) -> Self;
57 /// # Safety
58 /// The retained identity is live in this exact `Self` domain with unchanged logical identity.
59 /// Implementations return that exact destination identity.
60 unsafe fn rebuild<K: Key<Raw = Self::Raw>>(stored: Stored<K>) -> Self {
61 // SAFETY: the caller preserves the emitted identity in this destination domain.
62 Self::from_raw(unsafe { Stored::new(stored.into_raw()) })
63 }
64 fn decode(raw: Self::Raw) -> Option<Self>;
65}
66
67/// Stored representation of one external forward link.
68/// # Safety
69/// `NONE` decodes to `None`; present links and live items round-trip exactly.
70pub unsafe trait Link: Copy + Eq {
71 type Item: Copy + Eq;
72 const NONE: Self;
73 fn item(self) -> Option<Self::Item>;
74 /// Stores one live item without changing its identity.
75 /// # Safety
76 /// `item` must be live in this link's exact domain.
77 unsafe fn some(item: Self::Item) -> Self;
78}
79
80/// # Safety
81/// The retained owner initializes this key and satisfies every ownership and state invariant of P.
82/// Shared source loans preserve those obligations without creating exclusive authority.
83pub unsafe trait Source<P = ()>: Sized {
84 type Key: Copy;
85 fn key(&self) -> Self::Key;
86}
87
88/// # Safety
89/// Dense ordinal values bijectively map to `0..=MAX`; conversions are inverse and `ZERO` maps to zero.
90/// In-domain conversions return normally without callbacks or storage reentry.
91pub unsafe trait Word: Copy + Eq {
92 const ZERO: Self;
93 const MAX: NonZero<usize>;
94 fn offset(self) -> usize;
95 /// # Safety
96 /// `offset` must not exceed [`Self::MAX`].
97 unsafe fn from_offset(offset: usize) -> Self;
98}
99
100pub(in crate::depot) use hooks::{
101 Detach, EndpointHook, EndpointWord, Insert, Neighbor, Pop, Removal, Splice,
102};
103pub(crate) use proof::Slot;
104mod arena;
105pub use arena::Arena;
106mod words;
107pub use words::Words;
108mod hooks;
109pub use hooks::{Hooks, Node};
110
111/// An immutable u32 count retaining its original domain proof.
112/// # Safety
113/// Every copy reports the same count within MIN..=MAX; count is zero or count - 1 is at most I::MAX.
114pub unsafe trait Count<I: Compact = u32>: Copy {
115 const MIN: u32 = 0;
116 const MAX: u32 = u32::MAX;
117 fn count(self) -> capacity::Count;
118}
119
120/// An exact input traversal retaining its terminal operation state.
121/// # Safety
122/// The remaining count equals future items and never exceeds u32::MAX.
123pub unsafe trait Exact: Iterator {
124 type Output;
125 fn remaining(&self) -> capacity::Count;
126 /// # Safety
127 /// Iteration reached its terminal None without an intervening mutation.
128 unsafe fn finish(self) -> Self::Output;
129}
130
131/// Unchanged inputs bound to their exact slot demand.
132/// # Safety
133/// The reported count belongs to this unchanged input until it starts or is rejected.
134pub unsafe trait Input<T>: Sized {
135 type Item;
136 type Error;
137 type Context;
138 type Output;
139 fn count(&self) -> capacity::Count;
140 fn reject(self, error: capacity::Shortage) -> Self::Error;
141}
142
143/// An input whose start needs no further admission.
144/// # Safety
145/// Starting preserves the count, original owner, operation, and all lifetimes.
146pub unsafe trait Start<T>: Input<T> {
147 fn start(
148 self,
149 ) -> (
150 impl Exact<Item = Self::Item, Output = Self::Output>,
151 Self::Context,
152 );
153}
154
155/// An input whose start can reject additional resource admission.
156/// # Safety
157/// Success preserves the input proof; rejection leaves the reserved slots unused.
158pub unsafe trait TryStart<T>: Input<T> {
159 fn try_start(self) -> Started<Self, T, impl Exact<Item = Self::Item, Output = Self::Output>>;
160}
161
162/// Native positions in the fixed domain `0..N`.
163/// # Safety
164/// Values must identify positions below `N` bijectively; reconstruction is inverse.
165pub unsafe trait BitIndex<const N: usize>: Copy {
166 fn index(self) -> usize;
167 /// # Safety
168 /// The position must be below `N`, and `N` must be at most sixteen.
169 unsafe fn from_index(index: usize) -> Self;
170}
171
172/// A retained capability for one stationary set owner.
173/// # Safety
174/// Projections are pure; every projection and move retains the same live owner, extent, and lifetime.
175pub unsafe trait SetSource<Tag, Raw, const N: usize> {
176 type Mode;
177
178 fn planes(&self) -> &set::State<Tag, Raw, N, Self::Mode>;
179}
180
181/// A storage owner whose exclusive borrow excludes every other plane access.
182/// # Safety
183/// No independent handle may access these words while this owner is exclusively borrowed.
184pub unsafe trait Bitmap<W: bitmap::Width = usize>: Words<W> {}
185
186/// # Safety
187/// Stable disjoint domains retain their heads; tagged operations own mutations and `&mut Self` excludes competing access.
188/// Projections return normally without reentering the topology.
189pub unsafe trait TagStore {
190 type Head: tagged::raw::Head;
191 type Heads: AsRef<[Self::Head]> + ?Sized;
192 fn heads(&self) -> &Self::Heads;
193 fn capacity(&self) -> usize;
194 /// # Safety
195 /// The index names an initialized node in this exact owner.
196 unsafe fn hook(&self, index: Index) -> &tagged::Hook;
197}
198/// An entry whose destination belongs to its own store.
199/// # Safety
200/// The lane belongs to TagEntry::store; its projection returns normally without topology reentry or mutation.
201pub unsafe trait TagTarget: TagEntry {
202 fn lane(&self) -> tagged::Endpoint<&Self::Store>;
203}
204mod tagentry;
205pub use tagentry::TagEntry;
206
207/// The exact backing and initialized logical range of one ring.
208/// # Safety
209/// State and backing agree: capacity fits Word, head is bounded, and `0..len` is initialized.
210pub unsafe trait RingStore {
211 type Item;
212 type Word: Word;
213 fn state(&self) -> ring::State<Self::Word>;
214 fn capacity(&self) -> usize;
215 fn entries(&self) -> *const mem::MaybeUninit<Self::Item>;
216}
217/// Exclusive access to the state and disjoint backing of one ring.
218/// # Safety
219/// Projection returns normally with this owner's exact state and complete backing of length RingStore::capacity.
220pub unsafe trait RingEdit: crate::depot::raw::RingStore {
221 /// Lends the two initialized runs under one exclusive owner loan.
222 /// # Safety
223 /// Preserve owner invariants after mutation, unless terminal ownership prevents reuse.
224 unsafe fn slices_mut(&mut self) -> (&mut [Self::Item], &mut [Self::Item]) {
225 // SAFETY: RingEdit retains the exact initialized logical range;
226 // the physical runs are disjoint under the complete exclusive owner loan.
227 unsafe {
228 let (state, entries) = self.parts_mut();
229 let (start, [front, back]) = state.prefix(entries.len(), state.len());
230 let entries = entries.as_mut_ptr().cast::<Self::Item>();
231 (
232 slice::from_raw_parts_mut(entries.add(start), front),
233 slice::from_raw_parts_mut(entries, back),
234 )
235 }
236 }
237
238 fn push<const FRONT: bool>(vacant: ring::Vacant<'_, Self>, value: Self::Item) {
239 // SAFETY: consuming vacancy retains the complete exclusive owner and one spare slot.
240 unsafe {
241 let (state, entries) = vacant.into_source().parts_mut();
242 let index = state.push::<FRONT>(entries.len());
243 (*entries.as_mut_ptr().add(index)).write(value);
244 }
245 }
246
247 /// # Safety
248 /// Preserve state, initialization, and ownership invariants unless terminal ownership prevents reuse.
249 unsafe fn parts_mut(
250 &mut self,
251 ) -> (
252 &mut ring::State<Self::Word>,
253 &mut [mem::MaybeUninit<Self::Item>],
254 );
255
256 /// # Safety
257 /// The caller retains an exclusive nonempty owner and must preserve its metadata.
258 /// Implementations must retain this exact owner and its initialized front.
259 unsafe fn front_raw(&mut self) -> ring::Front<'_, Self> {
260 unsafe { ring::Front::new(self) }
261 }
262
263 /// # Safety
264 /// The exclusive owner has spare capacity; the caller must preserve its metadata.
265 /// Implementations must retain this exact owner and its vacancy.
266 unsafe fn vacant_raw(&mut self) -> ring::Vacant<'_, Self> {
267 unsafe { ring::Vacant::new(self) }
268 }
269}
270mod ringcell;
271pub use ringcell::RingCell;
272pub(crate) use ringcell::drop_ring;
273
274/// Detaches one exact external head slot.
275/// # Safety
276/// Returns that item's stored successor after detaching the supplied live item.
277pub unsafe trait HeadPop<L: Link, I = ()>: Sized {
278 type Output;
279 /// # Safety
280 /// `item` is the exact live slot owned by this transition.
281 unsafe fn pop(self, item: L::Item, input: I) -> (L, Self::Output);
282 /// # Safety
283 /// This transition owns this exact current front and cannot reenter its head.
284 unsafe fn apply(self, front: head::Front<'_, L>, input: I) -> Self::Output {
285 unsafe { front.pop(self, input) }
286 }
287}
288
289/// Publishes one exact detached external slot.
290/// # Safety
291/// Stores `head` in that detached slot before returning its exact live identity.
292pub unsafe trait HeadPush<L: Link, I = ()>: Sized {
293 /// # Safety
294 /// This transition and `input` own the exact detached slot returned.
295 unsafe fn push(self, input: I, head: L) -> L::Item;
296 /// # Safety
297 /// This transition owns a detached slot in this exact head's storage and cannot reenter it.
298 unsafe fn apply(self, head: &head::Cell<L>, input: I) {
299 let item = unsafe { self.push(input, head.raw()) };
300 head.0.set(unsafe { L::some(item) });
301 }
302}
303
304/// Consumes one exact keyed slot into its next membership phase.
305/// # Safety
306/// Output preserves or consumes this slot's original owner and root authority.
307pub unsafe trait KeyFinish<const LINKED: bool, P = ()>: Sized {
308 type Output;
309 /// # Safety
310 /// The selected slot is a member when LINKED and canonically detached otherwise.
311 unsafe fn finish(self) -> Self::Output;
312}
313/// # Safety
314/// This exclusive root retains its selected slot authority, exact key/link pair and FIFO.
315/// The key index is below `u32::MAX` and excludes the FIFO's endpoint tags.
316/// Shared loans retain the initialized link and plane; escaping values preserve authority and membership.
317/// Neighbor projection returns the exact initialized slot's link without changing or reentering the topology.
318pub unsafe trait KeyOwner<P = ()>: Sized {
319 type Key: Key;
320 type Fifo;
321 fn parts(&self) -> (Self::Key, &keyed::Link<Self::Key, P>);
322 fn fifo(&self) -> &Self::Fifo;
323 fn link(live: Proof<(&Self, Index), Initialized<P>>) -> &keyed::Link<Self::Key, P>;
324}
325/// # Safety
326/// Routing preserves this exact live slot, vacancy and exclusive root in its destination FIFO.
327pub unsafe trait KeyRoute<P = ()>: KeyOwner<P> {
328 type Target: KeyOwner<P, Key = Self::Key, Fifo = Self::Fifo>;
329 /// # Safety
330 /// This slot must be detached before changing its eligible FIFO.
331 unsafe fn route(self) -> Self::Target;
332}
333/// # Safety
334/// Retaining this source preserves its paired initialized storage, live endpoints and link plane.
335pub unsafe trait KeySource<P = ()> {
336 type Key: Key;
337 fn fifo(&self) -> &keyed::Fifo<Self::Key, P>;
338}
339/// # Safety
340/// Shared traversal preserves membership, links and identities.
341/// Projection returns the exact initialized slot's link without changing or reentering the topology.
342pub unsafe trait KeyRead<P = ()>: KeySource<P> {
343 fn link(live: Proof<(&Self, Index), Initialized<P>>) -> &keyed::Link<Self::Key, P>;
344}
345/// # Safety
346/// Every FIFO edge is live in this exact owner; selection retains its exclusive authority.
347pub unsafe trait KeyPlane<P = ()>:
348 KeySource<P, Key = <Self::Slot as KeyOwner<P>>::Key> + Sized
349{
350 type Slot: KeyOwner<P, Fifo = keyed::Fifo<Self::Key, P>>;
351 fn select(slot: Proof<(Self, Index), Initialized<P>>) -> Self::Slot;
352}
353/// # Safety
354/// Both disjoint FIFOs retain their exact initialized storage, plane and membership exclusively.
355pub unsafe trait KeyJoin<P = ()>: KeySource<P> {
356 fn target(&self) -> &keyed::Fifo<Self::Key, P>;
357 fn link(live: Proof<(&Self, Index), Initialized<P>>) -> &keyed::Link<Self::Key, P>;
358}
359/// # Safety
360/// This exclusive owner retains its heads/links with slots below `u32::MAX + 1 - N`.
361/// Shared aliases and payload operations preserve topology, live slots and exclusive authority.
362pub unsafe trait LaneSelect<const N: usize, const L: usize, P = ()>:
363 Sized + Project<Index, P> + AsRef<lanes::Fifo<Self::Key, N, P>>
364{
365 type Key: Key;
366 type Slot: KeyOwner<P, Key = Self::Key, Fifo = lanes::Fifo<Self::Key, N, P>>
367 + From<Self::Output>;
368}
369/// # Safety
370/// Encodings through `MAX` are complete, injective, and round-trip exactly.
371/// Both conversions are deterministic, non-panicking, and never invoke storage operations using this index domain.
372pub unsafe trait Compact: Copy {
373 const MAX: u32;
374 fn into_raw(self) -> u32;
375 /// Reconstructs an identity previously encoded by this domain.
376 /// # Safety
377 /// `raw <= Self::MAX` and belongs to this index domain.
378 unsafe fn from_raw(raw: u32) -> Self;
379}
380
381/// # Safety
382/// Nodes retain the exact topology owner; count bounds peak claims, including recycled slots.
383pub unsafe trait LinkedBatch<'a, T: 'a, Tag: 'a>: Sized {
384 type Output;
385 type Error;
386 fn nodes(&self) -> &'a Arena<T, Tag>;
387 fn count(&self) -> capacity::Count;
388 fn reject(self, error: capacity::Shortage) -> Self::Error;
389 fn run(self, reserve: &mut slots::Reserve<'a, T, Tag>) -> Self::Output;
390}
391
392/// An owned insertion carrying its original lane and unary slot entitlement.
393///
394/// # Safety
395/// The item owns this allocation's unused unary credit until its slot is removed.
396pub unsafe trait PoolInsert<'a, const TRACK: bool = true>: Sized {
397 type Item: 'a;
398 type State: 'a;
399 /// # Safety
400 /// The returned lane and item must be consumed by the same insertion.
401 unsafe fn into_parts(self) -> (Lane<'a, Self::Item, Self::State, TRACK>, Self::Item);
402}
403/// # Safety
404/// The credit reserves one unused slot in this exact FIFO's arena and remains
405/// paired with the returned entry until insertion or cancellation.
406pub unsafe trait Reserve<'fifo, 'pool: 'fifo, const TRACK: bool = true>: Sized {
407 type Item: 'pool;
408 type Credit;
409 type Reserved;
410
411 /// # Safety
412 /// Both returned owners must be consumed by this same reservation.
413 unsafe fn into_parts(self) -> (&'fifo mut Fifo<'pool, Self::Item, TRACK>, Self::Credit);
414
415 /// # Safety
416 /// Inputs come from this same reservation; retain them together through publication or cancellation.
417 /// The returned owner releases its vacant slot before returning unused credit on cancellation.
418 unsafe fn build(
419 slot: slots::Vacant<Self::Item, &'fifo mut Fifo<'pool, Self::Item, TRACK>>,
420 credit: Self::Credit,
421 ) -> Self::Reserved;
422}
423pub(crate) use arena::{EndsPop, SlotOwner};
424pub(in crate::depot) use arena::{
425 IndexedBlock, IndexedHook, IndexedMeta, IndexedState, PoolMutable, PoolPolicy, QueueBlock,
426 QueueSlot, SlabCapacity, SlabLinks, SlabSlot, StagedMove, StagedNode, StagedPhase, StagedState,
427};
428pub(in crate::depot) use hooks::{LaneInit, LaneStore, LaneUndo};
429
430mod entry;
431mod links;
432pub use entry::Entry;
433pub use links::Links;
434
435/// Start admission returns the unchanged input context or its exact rejection.
436type Started<S, T, I> = Result<(I, <S as Input<T>>::Context), <S as Input<T>>::Error>;
437
438/// Consumes a retained interior proof that already excludes live borrows.
439///
440/// The predicate carries the exclusivity obligation, so interior admission
441/// needs the same single check the predicate already performed at its source.
442pub trait Admit {
443 type Output;
444
445 fn admit(self) -> Self::Output;
446}