dope_core/driver/route/table/
mod.rs1use std::{iter::FusedIterator, ops::Range};
2
3use crate::driver::route::indices;
4pub mod borrows;
5pub mod bounds;
6mod capacity;
7pub mod conn;
8mod current;
9pub mod entries;
10mod key;
11mod slab;
12
13use std::{hash, marker};
14
15use o3::{
16 alloc,
17 depot::arena::slab::{external, external::shared},
18};
19
20use crate::driver::route;
21
22const PARTITIONS: usize = 2;
23
24type Storage<T, Tag> = external::Exclusive<T, route::Epoch, Tag, { u32::MAX }, PARTITIONS>;
25
26#[derive(Clone, Copy, PartialEq, Eq, Debug)]
27pub struct Invalid {
28 pub(in crate::driver) actual: usize,
29 pub(in crate::driver) minimum: usize,
30 pub(in crate::driver) maximum: usize,
31}
32
33#[derive(Clone, Copy, Debug)]
34#[repr(C)]
35pub struct Parts<Tag: route::Tag> {
36 epoch: route::Epoch,
37 slot: indices::SlotIndex,
38 tag: marker::PhantomData<*mut Tag>,
39}
40
41impl Invalid {
42 pub(crate) const fn from_bounds(actual: usize, minimum: usize, maximum: usize) -> Self {
43 Self {
44 actual,
45 minimum,
46 maximum,
47 }
48 }
49}
50
51impl<Tag: route::Tag> Parts<Tag> {
52 pub const fn new(slot: indices::SlotIndex, epoch: route::Epoch) -> Self {
53 Self {
54 epoch,
55 slot,
56 tag: marker::PhantomData,
57 }
58 }
59
60 pub const fn slot(self) -> indices::SlotIndex {
61 self.slot
62 }
63
64 pub const fn epoch(self) -> route::Epoch {
65 self.epoch
66 }
67
68 pub(in crate::driver::route::table) fn external(self) -> external::Key<route::Epoch, Tag> {
69 external::Key::new(self.slot().raw(), self.epoch())
70 }
71}
72
73impl<Tag: route::Tag> PartialEq for Parts<Tag> {
74 fn eq(&self, other: &Self) -> bool {
75 self.epoch == other.epoch && self.slot == other.slot
76 }
77}
78
79impl<Tag: route::Tag> Eq for Parts<Tag> {}
80
81impl<Tag: route::Tag> hash::Hash for Parts<Tag> {
82 fn hash<H: hash::Hasher>(&self, state: &mut H) {
83 self.epoch.hash(state);
84 self.slot.hash(state);
85 }
86}
87
88pub use capacity::Capacity;
89pub use current::Current;
90pub use key::Key;
91pub use slab::Slab;
92
93const _: () = {
94 assert!(std::mem::size_of::<Parts<route::KeyTag<1>>>() == 2 * std::mem::size_of::<u64>());
95};
96
97pub struct CellSlab<T, Tag: route::Tag> {
98 inner: shared::Storage<T, route::Epoch, Tag>,
99}
100
101impl<T, Tag: route::Tag> CellSlab<T, Tag> {
102 pub fn try_new(cap: Capacity) -> Result<Self, alloc::Error> {
104 Ok(Self {
105 inner: shared::Storage::try_new(cap.0)?,
106 })
107 }
108
109 pub fn is_empty(&self) -> bool {
110 self.inner.is_empty()
111 }
112
113 pub fn raw(&self) -> route::raw::Cell<'_, T, Tag> {
114 route::raw::Cell { inner: &self.inner }
115 }
116}
117
118#[derive(Clone, Debug)]
119pub struct Iter(Range<u32>);
120
121impl Iterator for Iter {
122 type Item = indices::SlotIndex;
123
124 fn next(&mut self) -> Option<Self::Item> {
125 self.0.next().map(Self::slot)
126 }
127
128 fn nth(&mut self, n: usize) -> Option<Self::Item> {
129 self.0.nth(n).map(Self::slot)
130 }
131
132 fn size_hint(&self) -> (usize, Option<usize>) {
133 let len = self.0.len();
134 (len, Some(len))
135 }
136}
137
138impl DoubleEndedIterator for Iter {
139 fn next_back(&mut self) -> Option<Self::Item> {
140 self.0.next_back().map(Self::slot)
141 }
142
143 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
144 self.0.nth_back(n).map(Self::slot)
145 }
146}
147
148impl Iter {
149 fn slot(raw: u32) -> indices::SlotIndex {
150 indices::SlotIndex::from_field(u64::from(raw))
151 }
152}
153
154impl ExactSizeIterator for Iter {}
155impl FusedIterator for Iter {}