Skip to main content

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}