Skip to main content

dope_core/driver/route/table/
mod.rs

1use 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    /// Reserves the complete interior-mutable target table transactionally.
103    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::new(&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 {}