Skip to main content

dope_core/driver/route/table/
slab.rs

1use o3::{alloc, depot::capacity};
2use table::borrows;
3
4use crate::driver::{route, route::indices, route::table};
5
6#[repr(transparent)]
7pub struct Slab<T, Tag: route::Tag> {
8    inner: table::Storage<T, Tag>,
9}
10
11impl<T, Tag: route::Tag> Slab<T, Tag> {
12    /// Reserves the complete typed target table transactionally.
13    pub fn try_new(cap: table::Capacity) -> Result<Self, alloc::Error> {
14        Ok(Self {
15            inner: table::Storage::try_new(cap.0)?,
16        })
17    }
18
19    /// Returns the immutable extent admitted when this route table was allocated.
20    pub fn capacity(&self) -> table::Capacity {
21        table::Capacity(self.inner.capacity())
22    }
23
24    pub fn len(&self) -> capacity::Count {
25        self.inner.len()
26    }
27
28    /// Returns capacity minus the number of initialized values.
29    ///
30    /// Forgotten reservations are included, so this is an upper bound on
31    /// reservable slots. Reservation still reports `Full` or `IdentityExhausted`.
32    pub fn available(&self) -> capacity::Count {
33        let total = self.inner.capacity();
34        let occupied = self.inner.len();
35        capacity::Count::new(total.raw() - occupied.raw())
36    }
37
38    pub fn is_empty(&self) -> bool {
39        self.inner.is_empty()
40    }
41
42    pub fn next_generation(&self) -> Option<route::Epoch> {
43        self.inner.next_generation()
44    }
45
46    pub fn get(&self, parts: table::Parts<Tag>) -> Option<&T> {
47        self.inner.get(parts.external())
48    }
49
50    pub fn contains(&self, parts: table::Parts<Tag>) -> bool {
51        self.get(parts).is_some()
52    }
53
54    pub fn key_at(&self, slot: indices::SlotIndex) -> Option<table::Key<Tag>> {
55        self.inner.key_at(slot.raw()).map(table::Key::new)
56    }
57
58    pub fn access(&mut self) -> borrows::Access<'_, T, Tag> {
59        borrows::Access(&mut self.inner)
60    }
61}