1use std::{
2 fmt::{Debug, Formatter},
3 marker::PhantomData,
4 sync::atomic::{AtomicUsize, Ordering},
5};
6
7pub struct AtomicIndex<T> {
8 index: AtomicUsize,
9 phantom: PhantomData<T>,
10}
11
12impl<T> Debug for AtomicIndex<T> {
13 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
14 write!(f, "AtomicIndex: {}", self.get())
15 }
16}
17
18unsafe impl<T> Send for AtomicIndex<T> {}
19unsafe impl<T> Sync for AtomicIndex<T> {}
20
21impl<T> Clone for AtomicIndex<T> {
22 fn clone(&self) -> Self {
23 Self {
24 index: AtomicUsize::new(self.index.load(Ordering::SeqCst)),
25 phantom: PhantomData,
26 }
27 }
28}
29
30impl<T> Default for AtomicIndex<T> {
31 fn default() -> Self {
32 Self::unassigned()
33 }
34}
35
36impl<T> AtomicIndex<T> {
37 pub fn unassigned() -> Self {
38 Self {
39 index: AtomicUsize::new(usize::MAX),
40 phantom: PhantomData,
41 }
42 }
43
44 fn new(index: usize) -> Self {
45 Self {
46 index: AtomicUsize::new(index),
47 phantom: PhantomData,
48 }
49 }
50
51 pub fn set(&self, index: usize) {
52 self.index.store(index, Ordering::SeqCst)
53 }
54
55 pub fn get(&self) -> usize {
56 self.index.load(Ordering::SeqCst)
57 }
58}
59
60pub struct SparseBuffer<T> {
61 vec: Vec<Option<T>>,
62 free: Vec<usize>,
63}
64
65impl<T> Default for SparseBuffer<T> {
66 fn default() -> Self {
67 Self {
68 vec: Default::default(),
69 free: Default::default(),
70 }
71 }
72}
73
74impl<T: Clone> Clone for SparseBuffer<T> {
75 fn clone(&self) -> Self {
76 Self {
77 vec: self.vec.clone(),
78 free: self.free.clone(),
79 }
80 }
81}
82
83impl<T> SparseBuffer<T> {
84 pub fn with_capacity(capacity: usize) -> Self {
85 Self {
86 vec: Vec::with_capacity(capacity),
87 free: vec![],
88 }
89 }
90
91 pub fn spawn(&mut self, payload: T) -> AtomicIndex<T> {
92 match self.free.pop() {
93 Some(free) => {
94 let old = self.vec[free].replace(payload);
95 debug_assert!(old.is_none());
96 AtomicIndex::new(free)
97 }
98 None => {
99 let index = AtomicIndex::new(self.vec.len());
100 self.vec.push(Some(payload));
101 index
102 }
103 }
104 }
105
106 pub fn free(&mut self, index: &AtomicIndex<T>) -> Option<T> {
107 self.free_raw(index.get())
108 }
109
110 pub fn free_raw(&mut self, index: usize) -> Option<T> {
111 match self.vec.get_mut(index) {
112 Some(entry) => match entry.take() {
113 Some(payload) => {
114 self.free.push(index);
115 Some(payload)
116 }
117 None => None,
118 },
119 None => None,
120 }
121 }
122
123 pub fn len(&self) -> usize {
124 self.vec.len()
125 }
126
127 pub fn is_empty(&self) -> bool {
128 self.filled() == 0
129 }
130
131 pub fn filled(&self) -> usize {
132 self.vec.len() - self.free.len()
133 }
134
135 pub fn is_index_valid(&self, index: &AtomicIndex<T>) -> bool {
136 self.get(index).is_some()
137 }
138
139 pub fn get(&self, index: &AtomicIndex<T>) -> Option<&T> {
140 self.get_raw(index.get())
141 }
142
143 pub fn get_mut(&mut self, index: &AtomicIndex<T>) -> Option<&mut T> {
144 self.get_mut_raw(index.get())
145 }
146
147 pub fn get_raw(&self, index: usize) -> Option<&T> {
148 self.vec.get(index).and_then(|entry| entry.as_ref())
149 }
150
151 pub fn get_mut_raw(&mut self, index: usize) -> Option<&mut T> {
152 self.vec.get_mut(index).and_then(|entry| entry.as_mut())
153 }
154
155 pub fn iter(&self) -> impl Iterator<Item = &T> {
156 self.vec.iter().filter_map(|entry| entry.as_ref())
157 }
158
159 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
160 self.vec.iter_mut().filter_map(|entry| entry.as_mut())
161 }
162
163 pub fn clear(&mut self) {
164 self.vec.clear();
165 self.free.clear();
166 }
167}