1use std::{
22 fmt::Debug,
23 sync::atomic::{AtomicUsize, Ordering},
24};
25
26#[derive(Debug)]
27pub struct AtomicIndex {
28 index: AtomicUsize,
29}
30
31impl Clone for AtomicIndex {
32 fn clone(&self) -> Self {
33 Self {
34 index: AtomicUsize::new(self.index.load(Ordering::SeqCst)),
35 }
36 }
37}
38
39impl Default for AtomicIndex {
40 fn default() -> Self {
41 Self::unassigned()
42 }
43}
44
45impl AtomicIndex {
46 pub const UNASSIGNED_INDEX: usize = usize::MAX;
47
48 pub fn unassigned() -> Self {
49 Self {
50 index: AtomicUsize::new(Self::UNASSIGNED_INDEX),
51 }
52 }
53
54 fn new(index: usize) -> Self {
55 Self {
56 index: AtomicUsize::new(index),
57 }
58 }
59
60 pub fn set(&self, index: usize) {
61 self.index.store(index, Ordering::SeqCst)
62 }
63
64 pub fn get(&self) -> usize {
65 self.index.load(Ordering::SeqCst)
66 }
67}
68
69pub struct SparseBuffer<T> {
70 vec: Vec<Option<T>>,
71 free: Vec<usize>,
72}
73
74impl<T> Default for SparseBuffer<T> {
75 fn default() -> Self {
76 Self {
77 vec: Default::default(),
78 free: Default::default(),
79 }
80 }
81}
82
83impl<T: Clone> Clone for SparseBuffer<T> {
84 fn clone(&self) -> Self {
85 Self {
86 vec: self.vec.clone(),
87 free: self.free.clone(),
88 }
89 }
90}
91
92impl<T> SparseBuffer<T> {
93 pub fn with_capacity(capacity: usize) -> Self {
94 Self {
95 vec: Vec::with_capacity(capacity),
96 free: vec![],
97 }
98 }
99
100 pub fn spawn(&mut self, payload: T) -> AtomicIndex {
101 match self.free.pop() {
102 Some(free) => {
103 let old = self.vec[free].replace(payload);
104 debug_assert!(old.is_none());
105 AtomicIndex::new(free)
106 }
107 None => {
108 let index = AtomicIndex::new(self.vec.len());
109 self.vec.push(Some(payload));
110 index
111 }
112 }
113 }
114
115 pub fn free(&mut self, index: &AtomicIndex) -> Option<T> {
116 self.free_raw(index.get())
117 }
118
119 pub fn free_raw(&mut self, index: usize) -> Option<T> {
120 match self.vec.get_mut(index) {
121 Some(entry) => match entry.take() {
122 Some(payload) => {
123 self.free.push(index);
124 Some(payload)
125 }
126 None => None,
127 },
128 None => None,
129 }
130 }
131
132 pub fn len(&self) -> usize {
133 self.vec.len()
134 }
135
136 pub fn is_empty(&self) -> bool {
137 self.filled() == 0
138 }
139
140 pub fn filled(&self) -> usize {
141 self.vec.len() - self.free.len()
142 }
143
144 pub fn is_index_valid(&self, index: &AtomicIndex) -> bool {
145 self.get(index).is_some()
146 }
147
148 pub fn get(&self, index: &AtomicIndex) -> Option<&T> {
149 self.get_raw(index.get())
150 }
151
152 pub fn get_mut(&mut self, index: &AtomicIndex) -> Option<&mut T> {
153 self.get_mut_raw(index.get())
154 }
155
156 pub fn get_raw(&self, index: usize) -> Option<&T> {
157 self.vec.get(index).and_then(|entry| entry.as_ref())
158 }
159
160 pub fn get_mut_raw(&mut self, index: usize) -> Option<&mut T> {
161 self.vec.get_mut(index).and_then(|entry| entry.as_mut())
162 }
163
164 pub fn iter(&self) -> impl Iterator<Item = &T> {
165 self.vec.iter().filter_map(|entry| entry.as_ref())
166 }
167
168 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
169 self.vec.iter_mut().filter_map(|entry| entry.as_mut())
170 }
171
172 pub fn clear(&mut self) {
173 self.vec.clear();
174 self.free.clear();
175 }
176}
177
178#[cfg(test)]
179mod test {
180
181 use super::*;
182
183 #[test]
184 fn atomic_index_get() {
185 let ai = AtomicIndex::new(42);
186 assert_eq!(ai.get(), 42);
187 }
188
189 #[test]
190 fn atomic_index_unassigned() {
191 let ai = AtomicIndex::unassigned();
192 assert_eq!(ai.get(), usize::MAX);
193 }
194
195 #[test]
196 fn atomic_index_new() {
197 let ai = AtomicIndex::new(42);
198 assert_eq!(ai.get(), 42);
199 }
200
201 #[test]
202 fn atomic_index_set() {
203 let ai = AtomicIndex::new(42);
204 assert_eq!(ai.get(), 42);
205
206 ai.set(1);
207 assert_eq!(ai.get(), 1);
208 }
209
210 #[test]
211 fn default_for_atomic_index() {
212 let mut ai = AtomicIndex::default();
213 assert_eq!(ai.index.get_mut(), &usize::MAX);
214 }
215
216 #[test]
217 fn clone_for_atomic_index() {
218 let ai = AtomicIndex::default();
219 let ai2 = ai.clone();
220 assert_eq!(ai2.get(), usize::MAX);
221 }
222
223 #[test]
224 fn default_for_sparse_buffer() {
225 let sb = SparseBuffer::<f32>::default();
226
227 assert_eq!(sb.vec, Vec::<Option<f32>>::default());
228 assert_eq!(sb.free, Vec::<usize>::default());
229 }
230
231 #[test]
232 fn clone_for_sparse_buffer() {
233 let sb = SparseBuffer::<f32>::default();
234 let sb2 = sb.clone();
235
236 assert_eq!(sb.vec, sb2.vec);
237 assert_eq!(sb.free, sb2.free);
238 }
239
240 #[test]
241 fn sparse_buffer_with_capacity() {
242 let sb = SparseBuffer::<f32>::with_capacity(10);
243
244 assert_eq!(sb.vec, Vec::with_capacity(10));
245 assert_eq!(sb.free, vec![]);
246 }
247
248 #[test]
249 fn sparse_buffer_len() {
250 let sb = SparseBuffer::<f32>::default();
251
252 assert_eq!(sb.len(), 0);
253 }
254
255 #[test]
256 fn sparse_buffer_filled() {
257 let sb = SparseBuffer {
258 vec: vec![None, Some(1)],
259 free: vec![],
260 };
261
262 assert_eq!(sb.filled(), 2);
263 }
264
265 #[test]
266 fn sparse_buffer_is_empty() {
267 let sb = SparseBuffer::<f32>::default();
268
269 assert!(sb.is_empty());
270
271 let sb = SparseBuffer {
272 vec: vec![None, Some(1)],
273 free: vec![],
274 };
275 assert!(!sb.is_empty());
276 }
277
278 #[test]
279 fn sparse_buffer_is_index_valid() {
280 let sb = SparseBuffer {
281 vec: vec![None, Some(1)],
282 free: vec![],
283 };
284
285 assert!(!sb.is_index_valid(&AtomicIndex::new(0)));
286 assert!(sb.is_index_valid(&AtomicIndex::new(1)));
287 }
288
289 #[test]
290 fn sparse_buffer_get_raw() {
291 let sb = SparseBuffer {
292 vec: vec![None, Some(1)],
293 free: vec![],
294 };
295
296 assert_eq!(sb.get_raw(0), None);
297 assert_eq!(sb.get_raw(1), Some(&1));
298 }
299
300 #[test]
301 fn sparse_buffer_get_mut_raw() {
302 let mut sb = SparseBuffer {
303 vec: vec![None, Some(1)],
304 free: vec![],
305 };
306
307 assert_eq!(sb.get_mut_raw(0), None);
308 assert_eq!(sb.get_mut_raw(1), Some(&mut 1));
309 }
310
311 #[test]
312 fn sparse_buffer_get() {
313 let sb = SparseBuffer {
314 vec: vec![None, Some(1)],
315 free: vec![],
316 };
317
318 assert_eq!(sb.get(&AtomicIndex::new(0)), None);
319 assert_eq!(sb.get(&AtomicIndex::new(1)), Some(&1));
320 }
321
322 #[test]
323 fn sparse_buffer_get_mut() {
324 let mut sb = SparseBuffer {
325 vec: vec![None, Some(1)],
326 free: vec![],
327 };
328
329 assert_eq!(sb.get_mut(&AtomicIndex::new(0)), None);
330 assert_eq!(sb.get_mut(&AtomicIndex::new(1)), Some(&mut 1));
331 }
332
333 #[test]
334 fn sparse_buffer_iter() {
335 let sb = SparseBuffer {
336 vec: vec![None, Some(1)],
337 free: vec![],
338 };
339
340 assert!(sb.iter().eq([&1]));
341 }
342
343 #[test]
344 fn sparse_buffer_iter_mut() {
345 let mut sb = SparseBuffer {
346 vec: vec![None, Some(1)],
347 free: vec![],
348 };
349
350 assert!(sb.iter_mut().eq([&mut 1]));
351 }
352
353 #[test]
354 fn sparse_buffer_clear() {
355 let mut sb = SparseBuffer {
356 vec: vec![None, Some(1)],
357 free: vec![1, 2],
358 };
359
360 sb.clear();
361 assert!(sb.vec.is_empty());
362 assert!(sb.free.is_empty());
363 }
364
365 #[test]
366 fn sparse_buffer_free_raw() {
367 let mut sb = SparseBuffer {
368 vec: vec![None, Some(1)],
369 free: vec![],
370 };
371
372 assert_eq!(sb.free_raw(42), None);
373 assert_eq!(sb.free_raw(0), None);
374 assert_eq!(sb.free_raw(1), Some(1));
375 assert_eq!(sb.vec, vec![None, None]);
376 assert_eq!(sb.free, vec![1]);
377 }
378
379 #[test]
380 fn sparse_buffer_free() {
381 let mut sb = SparseBuffer {
382 vec: vec![None, Some(1)],
383 free: vec![],
384 };
385
386 assert_eq!(sb.free(&AtomicIndex::new(0)), None);
387 assert_eq!(sb.free(&AtomicIndex::new(1)), Some(1));
388 assert_eq!(sb.vec, vec![None, None]);
389 assert_eq!(sb.free, vec![1]);
390 }
391
392 #[test]
393 fn sparse_buffer_spawn() {
394 let mut sb = SparseBuffer {
395 vec: vec![None, Some(1)],
396 free: vec![0],
397 };
398
399 assert_eq!(sb.spawn(42).get(), 0);
400 assert_eq!(sb.vec, vec![Some(42), Some(1)]);
401 assert_eq!(sb.free, vec![]);
402
403 assert_eq!(sb.spawn(5).get(), 2);
404 assert_eq!(sb.vec, vec![Some(42), Some(1), Some(5)]);
405 assert_eq!(sb.free, vec![]);
406 }
407}