Skip to main content

dope_core/driver/route/
mod.rs

1mod epoch;
2pub mod indices;
3use core::{hash, marker, mem, num};
4
5pub use epoch::Epoch;
6use indices::SlotIndex;
7pub use token::Token;
8pub(crate) use token::{Brand, OutboundKey};
9
10use crate::driver::route;
11
12pub mod lease;
13pub(in crate::driver) mod queues;
14pub mod raw;
15pub mod table;
16mod token;
17
18pub(crate) const FRAMEWORK: u8 = 255;
19pub(crate) const CAPACITY: usize = u8::MAX as usize + 1;
20
21pub(crate) const SHIFT: u32 = 56;
22pub(crate) const KIND_SHIFT: u32 = 48;
23pub const SLOT_BITS: u32 = 24;
24pub const SLOT_MASK: u64 = (1 << SLOT_BITS) - 1;
25pub(crate) const AUX_SHIFT: u32 = SLOT_BITS;
26pub(crate) const AUX_BITS: u32 = KIND_SHIFT - AUX_SHIFT;
27pub(crate) const AUX_VALUE_MASK: u32 = (1 << AUX_BITS) - 1;
28pub(crate) const AUX_MASK: u64 = (AUX_VALUE_MASK as u64) << AUX_SHIFT;
29
30/// A validated application route identity. The framework route cannot be
31/// constructed as an `Id`.
32#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
33#[repr(transparent)]
34pub struct Id(u8);
35
36/// The route namespace observed on a token or event.
37#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
38#[repr(transparent)]
39pub struct Route(u8);
40
41impl Id {
42    pub const fn fixed<const ID: u8>() -> Self {
43        const { assert!(ID != FRAMEWORK, "framework route is reserved") };
44        Self(ID)
45    }
46
47    /// Exact numeric identity, for hash domains and retained diagnostics.
48    pub const fn raw(self) -> u8 {
49        self.0
50    }
51
52    pub(crate) const fn into_route(self) -> Route {
53        Route(self.0)
54    }
55}
56
57impl Route {
58    pub(crate) const FRAMEWORK: Self = Self(FRAMEWORK);
59
60    pub(crate) const fn app(self) -> Option<Id> {
61        if self.is_framework() {
62            None
63        } else {
64            Some(Id(self.0))
65        }
66    }
67
68    pub(crate) const fn from_bits(raw: u8) -> Self {
69        Self(raw)
70    }
71
72    pub const fn is_framework(self) -> bool {
73        self.0 == FRAMEWORK
74    }
75
76    pub(crate) const fn raw(self) -> u8 {
77        self.0
78    }
79}
80
81impl From<Id> for Route {
82    fn from(id: Id) -> Self {
83        Self(id.raw())
84    }
85}
86
87impl TryFrom<Route> for Id {
88    type Error = Route;
89
90    fn try_from(route: Route) -> Result<Self, Self::Error> {
91        route.app().ok_or(route)
92    }
93}
94
95/// A route tag carrying its operation class as a type.
96///
97///
98#[derive(Clone, Copy, Debug)]
99pub struct KeyTag<const ROUTE: u8, C: kind::Class = kind::Any>(marker::PhantomData<C>);
100
101/// A framework-owned route tag for one registered operation class.
102#[derive(Clone, Copy)]
103pub struct FrameworkTag<C: kind::Class>(marker::PhantomData<C>);
104
105/// A route tag carries its identity through every invariant branded target.
106pub trait Tag: Copy {
107    const ROUTE: Route;
108    type Class: kind::Class;
109}
110
111/// Proves that a target tag may be materialized as one operation class.
112pub trait Select<C: kind::Class>: Tag {}
113
114/// A route tag proven to belong to the application namespace.
115pub trait App: Tag + kind::Sealed {
116    const ID: Id;
117}
118
119/// One application route identity usable in every operation class.
120///
121/// It carries [`Select`]'s class selection instead of a `const ID: u8` brand,
122/// so it adds no authority the class marker withheld.
123pub trait Identity:
124    App<Class = kind::Any>
125    + Eq
126    + hash::Hash
127    + Materialize<kind::Accept>
128    + Materialize<kind::Recv>
129    + Materialize<kind::Send>
130    + Materialize<kind::Socket>
131    + Materialize<kind::Connect>
132    + Materialize<kind::Shutdown>
133    + Materialize<kind::Open>
134    + Materialize<kind::OneShot>
135    + Materialize<kind::TaskQueue>
136    + Materialize<kind::Tuning>
137    + Materialize<kind::Write>
138    + Materialize<kind::Sync>
139{
140}
141
142/// One route identity materialized as a specific operation class.
143///
144/// The class a route is used in is part of the tag's type, so naming it is a
145/// type-level projection this trait carries for an unspecified class.
146pub trait Materialize<C: kind::Class>: Tag<Class = kind::Any> {
147    type With: App<Class = C> + Select<C>;
148}
149
150impl<const ROUTE: u8> Identity for KeyTag<ROUTE, kind::Any> {}
151
152impl<const ROUTE: u8, C: kind::Class> Materialize<C> for KeyTag<ROUTE, kind::Any>
153where
154    KeyTag<ROUTE, C>: App<Class = C> + Select<C>,
155{
156    type With = KeyTag<ROUTE, C>;
157}
158
159/// A tag carries only its route and class as types, so every value of one tag
160/// type is the same identity and hashes by that route.
161impl<const ROUTE: u8, C: kind::Class> PartialEq for KeyTag<ROUTE, C> {
162    fn eq(&self, _: &Self) -> bool {
163        true
164    }
165}
166
167impl<const ROUTE: u8, C: kind::Class> Eq for KeyTag<ROUTE, C> {}
168
169impl<const ROUTE: u8, C: kind::Class> hash::Hash for KeyTag<ROUTE, C> {
170    fn hash<H: hash::Hasher>(&self, state: &mut H) {
171        state.write_u8(ROUTE);
172    }
173}
174
175impl<const ROUTE: u8, C: kind::Class> Tag for KeyTag<ROUTE, C> {
176    const ROUTE: Route = Id::fixed::<ROUTE>().into_route();
177    type Class = C;
178}
179
180impl<const ROUTE: u8, C: kind::Class> App for KeyTag<ROUTE, C> {
181    const ID: Id = Id::fixed::<ROUTE>();
182}
183
184impl<const ROUTE: u8, C: kind::Class> kind::Sealed for KeyTag<ROUTE, C> {}
185
186impl<C: kind::Class> Tag for FrameworkTag<C> {
187    const ROUTE: Route = Route::FRAMEWORK;
188    type Class = C;
189}
190
191impl<T: Tag<Class = kind::Any>, C: kind::Class> Select<C> for T {}
192/// One operation identity branded by its driver lifetime and route.
193#[derive(Clone, Copy)]
194#[repr(transparent)]
195pub struct Operation<'d, T: Tag, C: kind::Class = <T as Tag>::Class> {
196    token: Token,
197    driver: Brand<'d, T>,
198    class: marker::PhantomData<C>,
199}
200
201impl<'d, T: Tag, C: kind::Class> Operation<'d, T, C> {
202    pub(super) const fn new(token: Token, driver: Brand<'d, T>) -> Self {
203        Self {
204            token,
205            driver,
206            class: marker::PhantomData,
207        }
208    }
209
210    pub fn matches(self, target: Erased<'d, C>) -> bool {
211        self.token == target.token
212    }
213
214    pub const fn parts(self) -> table::Parts<T> {
215        table::Parts::new(self.token.slot(), self.token.epoch())
216    }
217
218    pub const fn erase_route(self) -> Erased<'d, C> {
219        Erased::new(self.token, self.driver.driver).bind(kind::Witness(self.class))
220    }
221
222    pub(crate) const fn into_token(self) -> Token {
223        self.token
224    }
225}
226
227impl<T: Tag, C: kind::Class> PartialEq for Operation<'_, T, C> {
228    fn eq(&self, other: &Self) -> bool {
229        self.token == other.token
230    }
231}
232
233impl<T: Tag, C: kind::Class> Eq for Operation<'_, T, C> {}
234
235impl<T: Tag, C: kind::Class> hash::Hash for Operation<'_, T, C> {
236    fn hash<H: hash::Hasher>(&self, state: &mut H) {
237        self.token.hash(state);
238    }
239}
240
241/// Operation identity after deliberately erasing only its route tag.
242#[derive(Clone, Copy)]
243#[repr(transparent)]
244pub struct Erased<'d, C: kind::Class> {
245    pub(in crate::driver) token: Token,
246    pub(in crate::driver) driver: super::Invariant<'d>,
247    pub(in crate::driver) class: marker::PhantomData<C>,
248}
249
250impl<'d> Erased<'d, kind::Any> {
251    pub(in crate::driver) const fn new(token: Token, driver: super::Invariant<'d>) -> Self {
252        Self {
253            token,
254            driver,
255            class: marker::PhantomData,
256        }
257    }
258
259    pub(crate) const fn bind<C: kind::Class>(self, proof: kind::Witness<C>) -> Erased<'d, C> {
260        let kind::Witness(class) = proof;
261        Erased {
262            token: self.token,
263            driver: self.driver,
264            class,
265        }
266    }
267}
268
269impl<'d, C: kind::Class> Erased<'d, C> {
270    pub fn matches(self, target: Self) -> bool {
271        self.token == target.token
272    }
273
274    pub const fn route(self) -> Route {
275        self.token.route()
276    }
277
278    pub const fn slot(self) -> SlotIndex {
279        self.token.slot()
280    }
281
282    pub const fn epoch(self) -> Epoch {
283        self.token.epoch()
284    }
285
286    pub(crate) const fn into_token(self) -> Token {
287        self.token
288    }
289}
290
291/// A class-typed operation that belongs to another route.
292pub struct Mismatch<'d, T: Tag, C: kind::Class> {
293    target: Erased<'d, C>,
294    tag: marker::PhantomData<T>,
295}
296
297impl<'d, T: Tag, C: kind::Class> Mismatch<'d, T, C> {
298    const fn new(target: Erased<'d, C>) -> Self {
299        Self {
300            target,
301            tag: marker::PhantomData,
302        }
303    }
304
305    pub fn into_target(self) -> Erased<'d, C> {
306        self.target
307    }
308}
309
310pub mod kind;
311
312pub const SHUTDOWN: Control = Control::new(<kind::Shutdown as kind::Class>::CODE, SlotIndex::ZERO);
313
314const _: () = {
315    assert!(mem::size_of::<Erased<'static, kind::Send>>() == mem::size_of::<Token>());
316    assert!(mem::align_of::<Erased<'static, kind::Send>>() == mem::align_of::<Token>());
317    assert!(mem::size_of::<Mismatch<'static, KeyTag<1>, kind::Send>>() == mem::size_of::<Token>());
318};
319const _: () = assert!(mem::size_of::<Id>() == mem::size_of::<u8>());
320const _: () = assert!(mem::size_of::<Route>() == mem::size_of::<u8>());
321const _: () = {
322    assert!(mem::size_of::<Operation<'static, KeyTag<1>>>() == mem::size_of::<Token>());
323    assert!(mem::align_of::<Operation<'static, KeyTag<1>>>() == mem::align_of::<Token>());
324};
325
326/// One framework control decoded without manufacturing a keyed identity.
327#[derive(Clone, Copy, Eq, PartialEq, Debug)]
328#[repr(transparent)]
329pub struct Control(num::NonZero<u64>);
330
331impl From<Control> for num::NonZero<u64> {
332    fn from(control: Control) -> Self {
333        control.0
334    }
335}
336
337impl Control {
338    pub(crate) const fn new(kind: kind::Code, slot: indices::SlotIndex) -> Self {
339        let raw = ((route::FRAMEWORK as u64) << route::SHIFT)
340            | ((kind.raw() as u64) << route::KIND_SHIFT)
341            | slot.raw() as u64;
342        // SAFETY: the nonzero framework route occupies the high byte.
343        Self(unsafe { num::NonZero::<u64>::new_unchecked(raw) })
344    }
345
346    pub const fn slot(self) -> indices::SlotIndex {
347        indices::SlotIndex::from_field(self.0.get())
348    }
349}
350
351impl TryFrom<u64> for Control {
352    type Error = u64;
353
354    fn try_from(raw: u64) -> Result<Self, Self::Error> {
355        if (raw >> route::SHIFT) as u8 != route::FRAMEWORK {
356            return Err(raw);
357        }
358        // SAFETY: a framework-tagged high byte makes the complete word nonzero.
359        Ok(Self(unsafe { num::NonZero::<u64>::new_unchecked(raw) }))
360    }
361}
362
363const _: () = {
364    assert!(mem::size_of::<Token>() == 2 * mem::size_of::<u64>());
365    assert!(mem::size_of::<Option<Token>>() == mem::size_of::<Token>());
366    assert!(mem::size_of::<Control>() == mem::size_of::<u64>());
367    assert!(mem::size_of::<Option<Control>>() == mem::size_of::<Control>());
368};
369
370/// Zero-sized constructor branding table identities with one driver.
371#[derive(Clone, Copy)]
372pub struct Space<'d, Tag: route::Tag> {
373    pub(in crate::driver) driver: route::Brand<'d, Tag>,
374}
375
376impl<'d, Tag: route::Tag> Space<'d, Tag> {
377    pub const fn bind(
378        self,
379        slot: indices::SlotIndex,
380        epoch: route::Epoch,
381    ) -> route::Target<'d, Tag> {
382        route::Target::from_parts(table::Parts::new(slot, epoch), self.driver)
383    }
384
385    pub fn parse<C: kind::Class>(
386        self,
387        target: route::Erased<'d, C>,
388    ) -> Result<route::Operation<'d, Tag, C>, route::Mismatch<'d, Tag, C>>
389    where
390        Tag: route::Select<C>,
391    {
392        if target.route() != Tag::ROUTE {
393            return Err(route::Mismatch::new(target));
394        }
395        Ok(route::Operation::new(target.into_token(), self.driver))
396    }
397}
398
399const _: () = assert!(mem::size_of::<Space<'static, route::KeyTag<1>>>() == 0);
400
401/// One generation-checked target branded by its driver lifetime and route.
402///
403#[derive(Clone, Copy, Debug)]
404#[repr(transparent)]
405pub struct Target<'d, Tag: route::Tag> {
406    parts: table::Parts<Tag>,
407    pub(in crate::driver) driver: route::Brand<'d, Tag>,
408}
409
410impl<'d, Tag: route::Tag> Target<'d, Tag> {
411    pub(in crate::driver::route) const fn from_parts(
412        parts: table::Parts<Tag>,
413        driver: route::Brand<'d, Tag>,
414    ) -> Self {
415        Self { parts, driver }
416    }
417
418    pub const fn parts(self) -> table::Parts<Tag> {
419        self.parts
420    }
421
422    pub const fn slot(self) -> indices::SlotIndex {
423        self.parts.slot()
424    }
425
426    pub const fn epoch(self) -> route::Epoch {
427        self.parts.epoch()
428    }
429
430    pub const fn bind<T>(self, value: T) -> route::Bound<'d, Tag, T> {
431        route::Bound::new(self, value)
432    }
433
434    pub const fn operation<C: kind::Class>(self) -> route::Operation<'d, Tag, C>
435    where
436        Tag: route::Select<C>,
437    {
438        let Self { parts, driver } = self;
439        route::Operation::new(route::Token::encode::<Tag, C>(parts), driver)
440    }
441
442    pub const fn dispatch(self) -> route::Operation<'d, Tag> {
443        let Self { parts, driver } = self;
444        route::Operation::new(route::Token::from_parts(parts), driver)
445    }
446}
447
448impl<'d, Tag: route::Tag, C: kind::Class> From<&route::Operation<'d, Tag, C>> for Target<'d, Tag> {
449    fn from(op: &route::Operation<'d, Tag, C>) -> Self {
450        Self {
451            parts: op.parts(),
452            driver: op.driver,
453        }
454    }
455}
456
457impl<Tag: route::Tag> PartialEq for Target<'_, Tag> {
458    fn eq(&self, other: &Self) -> bool {
459        self.parts == other.parts
460    }
461}
462
463impl<Tag: route::Tag> Eq for Target<'_, Tag> {}
464
465impl<Tag: route::Tag> hash::Hash for Target<'_, Tag> {
466    fn hash<H: hash::Hasher>(&self, state: &mut H) {
467        self.parts.hash(state);
468    }
469}
470
471const _: () = {
472    assert!(mem::size_of::<Target<'static, route::KeyTag<1>>>() == mem::size_of::<route::Token>());
473    assert!(
474        mem::align_of::<Target<'static, route::KeyTag<1>>>() == mem::align_of::<route::Token>()
475    );
476};
477
478/// Affine submission input paired with its exact target.
479///
480#[must_use = "bound submission input must be submitted or dropped"]
481pub struct Bound<'d, Tag: route::Tag, T> {
482    target: route::Target<'d, Tag>,
483    value: T,
484}
485
486impl<'d, Tag: route::Tag, T> Bound<'d, Tag, T> {
487    pub(in crate::driver::route) const fn new(target: route::Target<'d, Tag>, value: T) -> Self {
488        Self { target, value }
489    }
490
491    pub(crate) fn into_parts(self) -> (route::Target<'d, Tag>, T) {
492        (self.target, self.value)
493    }
494}