Skip to main content

dope_core/driver/flight/
mod.rs

1pub(crate) mod raw;
2
3use std::{fmt, io, marker, mem, rc};
4
5use o3::collections::completion::narrow;
6
7use crate::driver::{self, route};
8
9type Invariant<'d> = marker::PhantomData<(fn(&'d ()) -> &'d (), rc::Rc<()>)>;
10
11const INDEX_BITS: u32 = route::SLOT_BITS;
12const GENERATION_BITS: u32 = 32;
13type InnerArena = narrow::Arena<route::Token, INDEX_BITS, GENERATION_BITS>;
14type InnerEcho = narrow::Echo<route::Token, INDEX_BITS, GENERATION_BITS>;
15type InnerSlots<'d> = narrow::Slots<'d, route::Token, INDEX_BITS, GENERATION_BITS>;
16type InnerReservation<'d> = narrow::Reservation<'d, route::Token, INDEX_BITS, GENERATION_BITS>;
17type InnerLease<'d> = narrow::Lease<'d, route::Token, INDEX_BITS, GENERATION_BITS>;
18type InnerResolved<'q> = narrow::Resolved<'q, route::Token, INDEX_BITS, GENERATION_BITS>;
19type InnerDrain<'q> = narrow::Drain<'q, route::Token, INDEX_BITS, GENERATION_BITS>;
20
21#[repr(transparent)]
22pub(crate) struct Arena(InnerArena);
23
24struct Owner<'a, 'd> {
25    arena: &'a mut InnerArena,
26    driver: driver::Reference<'d>,
27}
28
29#[doc(hidden)]
30#[repr(transparent)]
31pub struct Slots<'d, Tag: route::Tag> {
32    slots: InnerSlots<'d>,
33    driver: Invariant<'d>,
34    tag: marker::PhantomData<Tag>,
35}
36
37#[must_use = "a reserved flight must be committed or released"]
38#[repr(transparent)]
39pub(crate) struct Reservation<'d> {
40    reservation: InnerReservation<'d>,
41    driver: Invariant<'d>,
42}
43
44#[must_use = "a live flight must reach terminal completion or quiescence"]
45#[repr(transparent)]
46pub struct Flight<'d> {
47    flight: InnerLease<'d>,
48    driver: Invariant<'d>,
49}
50
51#[repr(transparent)]
52pub(crate) struct Completion<'q, 'd> {
53    completion: InnerResolved<'q>,
54    driver: Invariant<'d>,
55}
56
57pub(crate) struct Drain<'q, 'd> {
58    drain: InnerDrain<'q>,
59    driver: driver::Reference<'d>,
60}
61
62const _: () = {
63    assert!(mem::size_of::<raw::Echo>() == mem::size_of::<usize>());
64    assert!(mem::size_of::<Flight<'static>>() == mem::size_of::<usize>());
65    assert!(mem::size_of::<Option<Flight<'static>>>() == mem::size_of::<usize>());
66    assert!(mem::size_of::<Reservation<'static>>() == mem::size_of::<usize>());
67    assert!(mem::size_of::<Completion<'static, 'static>>() == 2 * mem::size_of::<usize>());
68    assert!(mem::size_of::<Drain<'static, 'static>>() == 2 * mem::size_of::<usize>());
69    assert!(mem::size_of::<Slots<'static, route::KeyTag<1>>>() == mem::size_of::<usize>());
70};
71
72impl Arena {
73    pub(crate) const fn new() -> Self {
74        Self(InnerArena::new())
75    }
76
77    pub(crate) fn try_slots<'d, Tag: route::Tag>(
78        &mut self,
79        capacity: usize,
80        driver: driver::Reference<'d>,
81    ) -> io::Result<Slots<'d, Tag>> {
82        Ok(Slots {
83            slots: InnerArena::try_slots(
84                Owner {
85                    arena: &mut self.0,
86                    driver,
87                },
88                capacity,
89            )?,
90            driver: marker::PhantomData,
91            tag: marker::PhantomData,
92        })
93    }
94}
95
96impl<'d, Tag: route::Tag> Slots<'d, Tag> {
97    pub(crate) fn reserve(&self, target: route::Operation<'d, Tag>) -> Option<Reservation<'d>> {
98        if Tag::KIND != 0 && target.kind() != Tag::KIND {
99            return None;
100        }
101        Some(Reservation {
102            reservation: self.slots.reserve(target.into_token())?,
103            driver: marker::PhantomData,
104        })
105    }
106}
107
108impl<'d> Reservation<'d> {
109    pub(crate) fn key(&self) -> raw::Echo {
110        raw::Echo::from_inner(self.reservation.key().echo())
111    }
112
113    pub(crate) fn commit(self) -> Flight<'d> {
114        Flight {
115            flight: self.reservation.commit(),
116            driver: marker::PhantomData,
117        }
118    }
119}
120
121impl<'q, 'd> Drain<'q, 'd> {
122    pub(in crate::driver) fn new(arena: &'q Arena, driver: driver::Reference<'d>) -> Self {
123        Self {
124            drain: arena.0.drain(),
125            driver,
126        }
127    }
128
129    pub(crate) fn driver(&self) -> driver::Reference<'d> {
130        self.driver
131    }
132
133    pub(crate) fn complete(&self, key: raw::Echo) -> Option<Completion<'q, 'd>> {
134        Some(Completion {
135            completion: self.drain.complete(key.into_inner())?,
136            driver: marker::PhantomData,
137        })
138    }
139}
140
141impl Completion<'_, '_> {
142    pub(crate) fn resolve(self, more: bool) -> Option<route::Token> {
143        self.completion.resolve(more)
144    }
145}
146
147impl<'d> Flight<'d> {
148    pub(crate) fn key(&self) -> raw::Echo {
149        raw::Echo::from_inner(self.flight.key().echo())
150    }
151
152    pub fn target(&self) -> route::Token {
153        self.flight.value()
154    }
155
156    pub(crate) fn target_erased(&self) -> route::Erased<'d> {
157        route::Erased::new(self.target())
158    }
159
160    pub fn matches(&self, target: route::Token) -> bool {
161        self.target() == target
162    }
163
164    pub fn complete(self) -> route::Token {
165        self.flight.complete()
166    }
167}
168
169impl fmt::Debug for Flight<'_> {
170    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
171        formatter
172            .debug_struct("Flight")
173            .field("target", &self.target())
174            .finish_non_exhaustive()
175    }
176}