dope_core/driver/route/table/
borrows.rs1use external::errors;
2use o3::depot::{
3 arena::slab::{self, external},
4 capacity,
5};
6use table::entries::{occupied, vacant};
7
8use crate::driver::{
9 route,
10 route::{indices, table, table::conn},
11};
12
13#[repr(transparent)]
14pub struct View<'a, T, Tag: route::Tag> {
15 pub(in crate::driver::route::table) inner: &'a table::Storage<T, Tag>,
16}
17
18impl<'a, T, Tag: route::Tag> View<'a, T, Tag> {
19 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 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<&'a T> {
47 self.inner.get(parts.external())
48 }
49
50 pub fn contains(self, parts: table::Parts<Tag>) -> bool {
51 self.inner.get(parts.external()).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
59#[repr(transparent)]
60pub struct Access<'a, T, Tag: route::Tag>(
61 pub(in crate::driver::route::table) &'a mut table::Storage<T, Tag>,
62);
63
64impl<'a, T, Tag: route::Tag> Access<'a, T, Tag> {
65 pub fn advance_to(self, floor: Option<route::Epoch>) {
66 self.0.advance_to(floor);
67 }
68
69 pub fn get(self, parts: table::Parts<Tag>) -> Option<&'a mut T> {
70 self.0.get_mut(parts.external())
71 }
72
73 pub fn occupied(self, parts: table::Parts<Tag>) -> Option<occupied::Entry<'a, T, Tag>> {
74 self.0.occupied(parts.external()).map(occupied::Entry)
75 }
76
77 pub fn try_occupied(
78 self,
79 parts: table::Parts<Tag>,
80 ) -> Result<occupied::Entry<'a, T, Tag>, errors::Lookup<route::Epoch, Tag>> {
81 let entry = self.0.try_occupied(parts.external())?;
82 Ok(occupied::Entry(entry))
83 }
84
85 pub fn at(self, index: indices::SlotIndex) -> Option<occupied::Entry<'a, T, Tag>> {
87 self.0.occupied_at(index.raw()).map(occupied::Entry)
88 }
89}
90
91#[repr(transparent)]
92pub struct Grant<'a, T, Tag: route::Tag>(
93 external::Grant<'a, T, route::Epoch, Tag, { u32::MAX }, { table::PARTITIONS }>,
94);
95
96impl<'a, T, Tag: route::Tag> Grant<'a, T, Tag> {
97 pub fn reserve(self) -> vacant::Entry<'a, T, Tag> {
98 vacant::Entry {
99 inner: self.0.reserve(),
100 }
101 }
102}
103
104#[repr(transparent)]
105pub struct Vacancy<'a, T, Tag: route::Tag>(
106 pub(in crate::driver::route::table) &'a mut table::Storage<T, Tag>,
107);
108
109impl<'a, T, Tag: route::Tag> Vacancy<'a, T, Tag> {
110 pub fn try_reserve(self) -> Result<vacant::Entry<'a, T, Tag>, slab::Vacancy> {
111 let grant = self.0.try_grant()?;
112 Ok(vacant::Entry {
113 inner: grant.reserve(),
114 })
115 }
116
117 pub fn try_at(self, slot: indices::SlotIndex) -> Result<Grant<'a, T, Tag>, slab::Vacancy> {
118 self.0.try_grant_at(slot.raw()).map(Grant)
119 }
120
121 pub fn try_head(self, capacity: conn::Capacity) -> Result<Grant<'a, T, Tag>, slab::Vacancy> {
122 self.0.try_grant_in(0..capacity.count().get()).map(Grant)
123 }
124
125 pub fn try_except(
127 self,
128 capacity: conn::Capacity,
129 excluded: indices::SlotIndex,
130 ) -> Result<Grant<'a, T, Tag>, slab::Vacancy> {
131 self.0
132 .try_except(0..capacity.count().get(), excluded.raw())
133 .map(Grant)
134 }
135}