1pub mod data;
4pub mod typed;
5
6mod drive;
7mod occupied;
8mod policy;
9mod records;
10mod runtime;
11mod vacant;
12
13use std::{convert::Infallible, marker};
14
15use o3::{
16 base::cell::region,
17 depot::{array::Index, map::direct},
18};
19pub use occupied::Occupied;
20pub use records::Records;
21pub use runtime::Runtime;
22pub use vacant::Vacant;
23
24use crate::manifold;
25use drive::TurnOutcome;
26
27const LANES: usize = 7;
28const CONTROL_READY: Index<LANES> = Index::at::<0>();
29const DATA_READY: Index<LANES> = Index::at::<1>();
30const CONNECTION_WAIT: Index<LANES> = Index::at::<2>();
31const STREAM_WAIT: Index<LANES> = Index::at::<3>();
32const CONTROL_EGRESS_WAIT: Index<LANES> = Index::at::<4>();
33const CONTROL_CONNECTION_WAIT: Index<LANES> = Index::at::<5>();
34const CONTROL_STREAM_WAIT: Index<LANES> = Index::at::<6>();
35const ALL: [Index<LANES>; LANES] = [
36 CONTROL_READY,
37 DATA_READY,
38 CONNECTION_WAIT,
39 STREAM_WAIT,
40 CONTROL_EGRESS_WAIT,
41 CONTROL_CONNECTION_WAIT,
42 CONTROL_STREAM_WAIT,
43];
44
45#[derive(Clone, Copy, PartialEq, Eq)]
47pub enum Wait {
48 Connection,
49 Stream,
50 Egress,
51}
52
53pub trait Block: Copy + Eq {
55 fn wait(self) -> Wait;
56}
57
58#[derive(Clone, Copy, PartialEq, Eq)]
60pub enum Wake<K> {
61 Connection,
62 Stream(K),
63}
64
65#[derive(Clone, Copy, PartialEq, Eq)]
67#[repr(u8)]
68pub enum Quiescence {
69 Busy,
70 Quiet,
71}
72
73const _: () = {
74 assert!(core::mem::size_of::<Quiescence>() == core::mem::size_of::<bool>());
75 assert!(core::mem::align_of::<Quiescence>() == core::mem::align_of::<bool>());
76};
77
78#[derive(Clone, Copy, PartialEq, Eq)]
80pub enum Egress {
81 Unchanged,
82 Released,
83}
84
85const _: () = {
86 assert!(core::mem::size_of::<Egress>() == core::mem::size_of::<bool>());
87 assert!(core::mem::align_of::<Egress>() == core::mem::align_of::<bool>());
88};
89
90#[derive(Clone, Copy, PartialEq, Eq)]
92#[must_use]
93pub enum Turn<B> {
94 Complete,
95 Progress,
96 Blocked(B),
97 Idle,
98}
99
100#[derive(Clone, Copy, PartialEq, Eq)]
102pub enum WorkClass {
103 Control,
104 Data,
105}
106
107impl WorkClass {
108 const fn ready_lane(self) -> Index<LANES> {
109 match self {
110 Self::Control => CONTROL_READY,
111 Self::Data => DATA_READY,
112 }
113 }
114
115 const fn blocked_lane(self, blocked: Option<Wait>) -> Index<LANES> {
116 match (blocked, self) {
117 (None, class) => class.ready_lane(),
118 (Some(Wait::Egress), Self::Control) => CONTROL_EGRESS_WAIT,
119 (Some(Wait::Egress), Self::Data) => DATA_READY,
120 (Some(Wait::Connection), Self::Control) => CONTROL_CONNECTION_WAIT,
121 (Some(Wait::Connection), Self::Data) => CONNECTION_WAIT,
122 (Some(Wait::Stream), Self::Control) => CONTROL_STREAM_WAIT,
123 (Some(Wait::Stream), Self::Data) => STREAM_WAIT,
124 }
125 }
126}
127
128#[derive(Clone, Copy, PartialEq, Eq)]
130pub struct ControlTurn<B> {
131 step: Step<B>,
132 activity: WorkClass,
133}
134
135impl<B> ControlTurn<B> {
136 pub const fn progress(next: WorkClass) -> Self {
137 Self {
138 step: Step::Progress(next),
139 activity: WorkClass::Control,
140 }
141 }
142
143 pub const fn blocked(block: B) -> Self {
144 Self {
145 step: Step::Blocked(block),
146 activity: WorkClass::Control,
147 }
148 }
149
150 pub const fn complete() -> Self {
151 Self {
152 step: Step::Complete,
153 activity: WorkClass::Control,
154 }
155 }
156
157 pub const fn idle() -> Self {
158 Self {
159 step: Step::Idle,
160 activity: WorkClass::Control,
161 }
162 }
163
164 fn into_parts(self) -> (Step<B>, WorkClass) {
165 (self.step, self.activity)
166 }
167}
168
169impl<B: Copy> ControlTurn<B> {
170 pub const fn new(egress: Turn<B>, next: WorkClass) -> Self {
171 Self::from_turn(egress, next, WorkClass::Control)
172 }
173
174 pub const fn fused(egress: Turn<B>, next: WorkClass) -> Self {
175 Self::from_turn(egress, next, WorkClass::Data)
176 }
177
178 const fn from_turn(egress: Turn<B>, next: WorkClass, activity: WorkClass) -> Self {
179 Self {
180 step: DataTurn::new(egress, next),
181 activity,
182 }
183 }
184}
185
186#[derive(Clone, Copy, PartialEq, Eq)]
188pub enum DataTurn<B> {
189 Complete,
190 Progress(WorkClass),
191 Blocked(B),
192 Idle,
193}
194
195impl<B: Copy> DataTurn<B> {
196 pub const fn new(egress: Turn<B>, next: WorkClass) -> Self {
197 match egress {
198 Turn::Complete => Self::Complete,
199 Turn::Progress => Self::Progress(next),
200 Turn::Blocked(block) => Self::Blocked(block),
201 Turn::Idle => Self::Idle,
202 }
203 }
204}
205
206type Step<B> = DataTurn<B>;
208
209pub enum Control<T, B, E = Infallible> {
211 Retain { value: T, turn: ControlTurn<B> },
212 Failed { value: T, error: E },
213 Complete,
214 Remove,
215}
216
217pub enum Settlement<T> {
219 Keep(T),
220 Remove,
221}
222
223pub enum Terminal<E> {
225 Complete,
226 Idle,
227 Failed(E),
228}
229
230#[derive(Clone, Copy, Default, PartialEq, Eq)]
232pub enum Activation<B> {
233 #[default]
234 Keep,
235 Activate {
236 blocked: Option<B>,
237 class: WorkClass,
238 },
239}
240
241impl<B> Activation<B> {
242 pub const fn data(blocked: Option<B>) -> Self {
243 Self::Activate {
244 blocked,
245 class: WorkClass::Data,
246 }
247 }
248
249 pub const fn control(blocked: Option<B>) -> Self {
250 Self::Activate {
251 blocked,
252 class: WorkClass::Control,
253 }
254 }
255}
256
257#[derive(Clone, Copy, PartialEq, Eq, Debug)]
259pub enum Error<E> {
260 Missing,
261 Rejected(E),
262}
263
264pub trait Settle<T> {
266 type Key: manifold::raw::Key;
267 type Error;
268
269 fn settle(
270 &mut self,
271 stream: Self::Key,
272 value: T,
273 terminal: Terminal<Self::Error>,
274 ) -> Settlement<T>;
275}
276
277#[repr(transparent)]
278pub struct Decision<'id, K> {
279 outcome: TurnOutcome<K>,
280 _scope: marker::PhantomData<region::Identity<'id>>,
281}
282
283impl<'id, K> Decision<'id, K> {
284 fn bind(outcome: TurnOutcome<K>, _scope: region::Identity<'id>) -> Self {
285 Self {
286 outcome,
287 _scope: marker::PhantomData,
288 }
289 }
290
291 const fn running(stream: K, activity: WorkClass) -> TurnOutcome<K> {
292 TurnOutcome::new(stream, activity, drive::Effect::None)
293 }
294
295 const fn blocked(stream: K, activity: WorkClass) -> TurnOutcome<K> {
296 TurnOutcome::new(stream, activity, drive::Effect::BlockData)
297 }
298}
299
300pub trait Driver<T>: Settle<T> {
302 type Block: Block;
303 type Permit;
304
305 fn permit(&mut self) -> Option<Self::Permit>;
306
307 fn control<'id>(
308 &mut self,
309 permit: Self::Permit,
310 entry: Occupied<'_, Self::Key, T, Self::Block, region::Identity<'id>>,
311 ) -> Decision<'id, Self::Key>;
312
313 fn data(
314 &mut self,
315 permit: Self::Permit,
316 stream: Self::Key,
317 value: &mut T,
318 ) -> Result<DataTurn<Self::Block>, Self::Error>;
319}
320
321#[derive(Clone, Copy, Default, PartialEq, Eq)]
323pub struct Report {
324 pub turns: usize,
325 pub completed: usize,
326}
327
328pub type InsertResult<K, T> = Result<(), Insert<K, T>>;
330
331#[must_use = "a rejected resident owner must be handled"]
333#[derive(Debug)]
334pub enum Insert<K, T> {
335 Full {
336 stream: K,
337 value: T,
338 used: usize,
339 limit: usize,
340 },
341 Occupied {
342 stream: K,
343 stored: K,
344 value: T,
345 },
346 Excluded {
347 stream: K,
348 value: T,
349 index: usize,
350 capacity: usize,
351 },
352}
353
354impl<K: manifold::raw::Key, T> Insert<K, T> {
355 pub(super) fn from_direct(error: direct::Error<K>, value: T) -> Self {
356 match error {
357 direct::Error::Outside {
358 key,
359 index,
360 capacity,
361 } => Self::Excluded {
362 stream: key,
363 value,
364 index,
365 capacity,
366 },
367 direct::Error::Occupied { key, stored } => Self::Occupied {
368 stream: key,
369 stored,
370 value,
371 },
372 }
373 }
374}