rafx_base/slab/
drop_slab.rs1use super::RawSlab;
2use super::RawSlabKey;
3use super::SlabIndexT;
4use crossbeam_channel::{Receiver, Sender};
5use std::marker::PhantomData;
6use std::sync::Arc;
7
8pub struct DropSlab<T> {
11 raw_slab: RawSlab<T>,
12 drop_tx: Sender<SlabIndexT>,
13 drop_rx: Receiver<SlabIndexT>,
14}
15
16impl<T> Default for DropSlab<T> {
17 fn default() -> Self {
18 Self::with_capacity(32)
19 }
20}
21
22impl<T> DropSlab<T> {
23 pub fn new() -> Self {
25 Default::default()
26 }
27
28 pub fn with_capacity(capacity: SlabIndexT) -> Self {
30 let (drop_tx, drop_rx) = crossbeam_channel::unbounded();
31 Self {
32 raw_slab: RawSlab::with_capacity(capacity),
33 drop_tx,
34 drop_rx,
35 }
36 }
37
38 pub fn process_drops(&mut self) {
39 for slab_index in self.drop_rx.try_iter() {
40 let raw_slab_key = RawSlabKey::<T>::new(slab_index);
41 self.raw_slab.free(raw_slab_key);
42 }
43 }
44
45 pub fn allocate(
46 &mut self,
47 value: T,
48 ) -> DropSlabKey<T> {
49 let slab_key = self.raw_slab.allocate(value);
50 DropSlabKey::new(slab_key.index(), self.drop_tx.clone())
51 }
52
53 pub fn get(
54 &self,
55 slab_key: &DropSlabKey<T>,
56 ) -> Option<&T> {
57 self.get_raw(RawSlabKey::new(slab_key.index()))
58 }
59
60 pub fn get_mut(
61 &mut self,
62 slab_key: &DropSlabKey<T>,
63 ) -> Option<&mut T> {
64 self.get_raw_mut(RawSlabKey::new(slab_key.index()))
65 }
66
67 pub fn get_raw(
68 &self,
69 raw_slab_key: RawSlabKey<T>,
70 ) -> Option<&T> {
71 self.raw_slab.get(raw_slab_key)
72 }
73
74 pub fn get_raw_mut(
75 &mut self,
76 raw_slab_key: RawSlabKey<T>,
77 ) -> Option<&mut T> {
78 self.raw_slab.get_mut(raw_slab_key)
79 }
80
81 pub fn iter_values(&self) -> impl Iterator<Item = &T> {
82 self.raw_slab.iter().map(move |(_, value)| value)
83 }
84
85 pub fn iter_values_mut(&mut self) -> impl Iterator<Item = &mut T> {
86 self.raw_slab.iter_mut().map(move |(_, value)| value)
87 }
88
89 pub fn allocated_count(&self) -> usize {
121 self.raw_slab.allocated_count()
122 }
123
124 pub fn storage_size(&self) -> usize {
125 self.raw_slab.storage_size()
126 }
127}
128
129pub struct RawDropSlabKeyInner {
130 raw_slab_index: SlabIndexT,
131 drop_tx: Sender<SlabIndexT>,
132}
133
134impl Drop for RawDropSlabKeyInner {
135 fn drop(&mut self) {
136 let _ = self.drop_tx.send(self.raw_slab_index);
138 }
139}
140
141pub struct DropSlabKey<T> {
142 inner: Arc<RawDropSlabKeyInner>,
143 _phantom: PhantomData<T>,
144}
145
146impl<T> Clone for DropSlabKey<T> {
147 fn clone(&self) -> Self {
148 Self {
149 inner: self.inner.clone(),
150 _phantom: Default::default(),
151 }
152 }
153}
154
155impl<T> std::fmt::Debug for DropSlabKey<T> {
156 fn fmt(
157 &self,
158 f: &mut std::fmt::Formatter<'_>,
159 ) -> std::fmt::Result {
160 f.debug_struct("DropSlabKey")
161 .field("index", &self.inner.raw_slab_index)
162 .finish()
163 }
164}
165
166impl<T> DropSlabKey<T> {
167 fn new(
168 raw_slab_index: SlabIndexT,
169 drop_tx: Sender<SlabIndexT>,
170 ) -> Self {
171 let inner = RawDropSlabKeyInner {
172 raw_slab_index,
173 drop_tx,
174 };
175
176 Self {
177 inner: Arc::new(inner),
178 _phantom: Default::default(),
179 }
180 }
181
182 pub fn index(&self) -> SlabIndexT {
183 self.inner.raw_slab_index
184 }
185
186 pub fn generic_drop_slab_key(&self) -> GenericDropSlabKey {
187 GenericDropSlabKey::new(self.inner.clone())
188 }
189}
190
191pub struct GenericDropSlabKey {
192 inner: Arc<RawDropSlabKeyInner>,
193}
194
195impl Clone for GenericDropSlabKey {
196 fn clone(&self) -> Self {
197 Self::new(self.inner.clone())
198 }
199}
200
201impl std::fmt::Debug for GenericDropSlabKey {
202 fn fmt(
203 &self,
204 f: &mut std::fmt::Formatter<'_>,
205 ) -> std::fmt::Result {
206 f.debug_struct("GenericDropSlabKey")
207 .field("index", &self.inner.raw_slab_index)
208 .finish()
209 }
210}
211
212impl GenericDropSlabKey {
213 fn new(inner: Arc<RawDropSlabKeyInner>) -> Self {
214 Self { inner }
215 }
216
217 pub fn index(&self) -> SlabIndexT {
218 self.inner.raw_slab_index
219 }
220
221 pub fn drop_slab_key<T>(&self) -> DropSlabKey<T> {
222 DropSlabKey {
223 inner: self.inner.clone(),
224 _phantom: Default::default(),
225 }
226 }
227}