dope_core/driver/flight/
mod.rs1pub(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}