1use std::{
3 fmt::{self, Debug},
4 hash::Hash,
5 marker::PhantomData,
6 ops,
7};
8
9#[cfg(test)]
10mod tests;
11
12pub trait NumericId: Copy + Clone + PartialEq + Eq + PartialOrd + Ord + Hash + Send + Sync {
14 type Rep;
15 type Atomic;
16 fn new(val: Self::Rep) -> Self;
17 fn from_usize(index: usize) -> Self;
18 fn index(self) -> usize;
19 fn rep(self) -> Self::Rep;
20 fn inc(self) -> Self {
21 Self::from_usize(self.index() + 1)
22 }
23}
24
25impl NumericId for usize {
26 type Rep = usize;
27 type Atomic = std::sync::atomic::AtomicUsize;
28 fn new(val: usize) -> Self {
29 val
30 }
31 fn from_usize(index: usize) -> Self {
32 index
33 }
34
35 fn rep(self) -> usize {
36 self
37 }
38
39 fn index(self) -> usize {
40 self
41 }
42}
43
44#[derive(Clone, PartialEq, Eq, Hash)]
49pub struct DenseIdMap<K, V> {
50 data: Vec<Option<V>>,
51 _marker: PhantomData<K>,
52}
53
54impl<K: NumericId + Debug, V: Debug> Debug for DenseIdMap<K, V> {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 let mut map = f.debug_map();
57 for (k, v) in self.iter() {
58 map.entry(&k, v);
59 }
60 map.finish()
61 }
62}
63
64impl<K, V> Default for DenseIdMap<K, V> {
65 fn default() -> Self {
66 Self {
67 data: Vec::new(),
68 _marker: PhantomData,
69 }
70 }
71}
72
73impl<K: NumericId, V> DenseIdMap<K, V> {
74 pub fn with_capacity(n: usize) -> Self {
76 let mut res = Self::new();
77 res.reserve_space(K::from_usize(n));
78 res
79 }
80
81 pub fn new() -> Self {
83 Self::default()
84 }
85
86 pub fn clear(&mut self) {
88 self.data.clear();
89 }
90
91 pub fn capacity(&self) -> usize {
93 self.data.capacity()
94 }
95
96 pub fn n_ids(&self) -> usize {
99 self.data.len()
100 }
101
102 pub fn insert(&mut self, key: K, value: V) {
104 self.reserve_space(key);
105 self.data[key.index()] = Some(value);
106 }
107
108 pub fn next_id(&self) -> K {
110 K::from_usize(self.data.len())
111 }
112
113 pub fn push(&mut self, val: V) -> K {
116 let res = self.next_id();
117 self.data.push(Some(val));
118 res
119 }
120
121 pub fn contains_key(&self, key: K) -> bool {
123 self.data.get(key.index()).is_some_and(Option::is_some)
124 }
125
126 pub fn get(&self, key: K) -> Option<&V> {
128 self.data.get(key.index())?.as_ref()
129 }
130
131 pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
133 self.reserve_space(key);
134 self.data.get_mut(key.index())?.as_mut()
135 }
136
137 pub fn unwrap_val(&mut self, key: K) -> V {
142 self.reserve_space(key);
143 self.data.get_mut(key.index()).unwrap().take().unwrap()
144 }
145
146 pub fn take(&mut self, key: K) -> Option<V> {
148 self.reserve_space(key);
149 self.data.get_mut(key.index()).unwrap().take()
150 }
151
152 pub fn get_or_insert(&mut self, key: K, f: impl FnOnce() -> V) -> &mut V {
155 self.reserve_space(key);
156 self.data[key.index()].get_or_insert_with(f)
157 }
158
159 pub fn raw(&self) -> &[Option<V>] {
160 &self.data
161 }
162
163 pub fn iter(&self) -> impl Iterator<Item = (K, &V)> {
164 self.data
165 .iter()
166 .enumerate()
167 .filter_map(|(i, v)| Some((K::from_usize(i), v.as_ref()?)))
168 }
169
170 pub fn iter_mut(&mut self) -> impl Iterator<Item = (K, &mut V)> {
171 self.data
172 .iter_mut()
173 .enumerate()
174 .filter_map(|(i, v)| Some((K::from_usize(i), v.as_mut()?)))
175 }
176
177 pub fn reserve_space(&mut self, key: K) {
179 let index = key.index();
180 if index >= self.data.len() {
181 self.data.resize_with(index + 1, || None);
182 }
183 }
184
185 pub fn drain(&mut self) -> impl Iterator<Item = (K, V)> + '_ {
186 self.data
188 .drain(..)
189 .enumerate()
190 .filter_map(|(i, v)| Some((K::from_usize(i), v?)))
191 }
192}
193
194impl<K: NumericId, V: Send + Sync> DenseIdMap<K, V> {
195 pub fn par_iter(&self) -> impl ParallelIterator<Item = (K, &V)> {
197 self.data
198 .par_iter()
199 .enumerate()
200 .filter_map(|(i, v)| Some((K::from_usize(i), v.as_ref()?)))
201 }
202
203 pub fn par_iter_mut(&mut self) -> impl ParallelIterator<Item = (K, &mut V)> {
205 self.data
206 .par_iter_mut()
207 .enumerate()
208 .filter_map(|(i, v)| Some((K::from_usize(i), v.as_mut()?)))
209 }
210}
211
212impl<K: NumericId, V> ops::Index<K> for DenseIdMap<K, V> {
213 type Output = V;
214
215 fn index(&self, key: K) -> &Self::Output {
216 self.get(key).unwrap()
217 }
218}
219
220impl<K: NumericId, V> ops::IndexMut<K> for DenseIdMap<K, V> {
221 fn index_mut(&mut self, key: K) -> &mut Self::Output {
222 self.get_mut(key).unwrap()
223 }
224}
225
226impl<K: NumericId, V: Default> DenseIdMap<K, V> {
227 pub fn get_or_default(&mut self, key: K) -> &mut V {
228 self.get_or_insert(key, V::default)
229 }
230}
231
232#[derive(Debug)]
233pub struct IdVec<K, V> {
234 data: Vec<V>,
235 _marker: std::marker::PhantomData<K>,
236}
237
238impl<K, V> IdVec<K, V> {
239 pub fn clear(&mut self) {
240 self.data.clear();
241 }
242 pub fn len(&self) -> usize {
243 self.data.len()
244 }
245 pub fn capacity(&self) -> usize {
246 self.data.capacity()
247 }
248}
249
250impl<K, V> Default for IdVec<K, V> {
251 fn default() -> IdVec<K, V> {
252 IdVec {
253 data: Default::default(),
254 _marker: std::marker::PhantomData,
255 }
256 }
257}
258
259impl<K, V: Clone> Clone for IdVec<K, V> {
260 fn clone(&self) -> Self {
261 IdVec {
262 data: self.data.clone(),
263 _marker: std::marker::PhantomData,
264 }
265 }
266}
267
268#[derive(Clone)]
270pub struct DenseIdMapWithReuse<K, V> {
271 data: DenseIdMap<K, V>,
272 free: Vec<K>,
273}
274
275impl<K, V> Default for DenseIdMapWithReuse<K, V> {
276 fn default() -> Self {
277 Self {
278 data: Default::default(),
279 free: Default::default(),
280 }
281 }
282}
283
284impl<K: NumericId, V> DenseIdMapWithReuse<K, V> {
285 pub fn reserve_slot(&mut self) -> K {
287 match self.free.pop() {
288 Some(res) => res,
289 None => {
290 let res = self.data.next_id();
291 self.data.reserve_space(res);
292 res
293 }
294 }
295 }
296
297 pub fn insert(&mut self, key: K, value: V) {
302 self.data.insert(key, value)
303 }
304
305 pub fn push(&mut self, value: V) -> K {
307 let res = self.reserve_slot();
308 self.insert(res, value);
309 res
310 }
311
312 pub fn take(&mut self, id: K) -> Option<V> {
314 let res = self.data.take(id);
315 if res.is_some() {
316 self.free.push(id);
317 }
318 res
319 }
320}
321
322impl<K: NumericId, V> std::ops::Index<K> for DenseIdMapWithReuse<K, V> {
323 type Output = V;
324 fn index(&self, key: K) -> &V {
325 &self.data[key]
326 }
327}
328
329impl<K: NumericId, V> std::ops::IndexMut<K> for DenseIdMapWithReuse<K, V> {
330 fn index_mut(&mut self, key: K) -> &mut V {
331 &mut self.data[key]
332 }
333}
334
335impl<K: NumericId, V> IdVec<K, V> {
336 pub fn with_capacity(cap: usize) -> IdVec<K, V> {
337 IdVec {
338 data: Vec::with_capacity(cap),
339 _marker: std::marker::PhantomData,
340 }
341 }
342
343 pub fn push(&mut self, elt: V) -> K {
344 let res = K::from_usize(self.data.len());
345 self.data.push(elt);
346 res
347 }
348
349 pub fn resize_with(&mut self, size: usize, init: impl FnMut() -> V) {
350 self.data.resize_with(size, init)
351 }
352
353 pub fn is_empty(&self) -> bool {
354 self.data.is_empty()
355 }
356
357 pub fn values(&self) -> impl Iterator<Item = &V> {
358 self.data.iter()
359 }
360
361 pub fn iter(&self) -> impl Iterator<Item = (K, &V)> {
362 self.data
363 .iter()
364 .enumerate()
365 .map(|(i, v)| (K::from_usize(i), v))
366 }
367 pub fn iter_mut(&mut self) -> impl Iterator<Item = (K, &mut V)> {
368 self.data
369 .iter_mut()
370 .enumerate()
371 .map(|(i, v)| (K::from_usize(i), v))
372 }
373 pub fn drain(&mut self) -> impl Iterator<Item = (K, V)> + '_ {
374 self.data
375 .drain(..)
376 .enumerate()
377 .map(|(i, v)| (K::from_usize(i), v))
378 }
379 pub fn get(&self, key: K) -> Option<&V> {
380 self.data.get(key.index())
381 }
382}
383
384impl<K: NumericId, V: Send + Sync> IdVec<K, V> {
385 pub fn par_iter_mut(&mut self) -> impl IndexedParallelIterator<Item = (K, &mut V)> {
386 self.data
387 .par_iter_mut()
388 .with_max_len(1)
389 .enumerate()
390 .map(|(i, v)| (K::from_usize(i), v))
391 }
392}
393
394impl<K: NumericId, V> ops::Index<K> for IdVec<K, V> {
395 type Output = V;
396
397 fn index(&self, key: K) -> &Self::Output {
398 &self.data[key.index()]
399 }
400}
401
402impl<K: NumericId, V> ops::IndexMut<K> for IdVec<K, V> {
403 fn index_mut(&mut self, key: K) -> &mut Self::Output {
404 &mut self.data[key.index()]
405 }
406}
407
408use rayon::iter::{
409 IndexedParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator,
410};
411
412#[macro_export]
413#[doc(hidden)]
414macro_rules! atomic_of {
415 (usize) => {
416 std::sync::atomic::AtomicUsize
417 };
418 (u8) => {
419 std::sync::atomic::AtomicU8
420 };
421 (u16) => {
422 std::sync::atomic::AtomicU16
423 };
424 (u32) => {
425 std::sync::atomic::AtomicU32
426 };
427 (u64) => {
428 std::sync::atomic::AtomicU64
429 };
430}
431
432#[macro_export]
433macro_rules! define_id {
434 ($v:vis $name:ident, $repr:tt) => { define_id!($v, $name, $repr, ""); };
435 ($v:vis $name:ident, $repr:tt, $doc:tt) => {
436 #[derive(Copy, Clone)]
437 #[doc = $doc]
438 $v struct $name {
439 rep: $repr,
440 }
441
442 impl PartialEq for $name {
443 fn eq(&self, other: &Self) -> bool {
444 self.rep == other.rep
445 }
446 }
447
448 impl Eq for $name {}
449
450 impl PartialOrd for $name {
451 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
452 Some(self.cmp(other))
453 }
454 }
455
456 impl Ord for $name {
457 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
458 self.rep.cmp(&other.rep)
459 }
460 }
461
462 impl std::hash::Hash for $name {
463 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
464 self.rep.hash(state);
465 }
466 }
467
468 impl $name {
469 #[allow(unused)]
470 $v const fn new_const(id: $repr) -> Self {
471 $name {
472 rep: id,
473 }
474 }
475
476 #[allow(unused)]
477 $v fn range(low: Self, high: Self) -> impl Iterator<Item = Self> {
478 use $crate::NumericId;
479 (low.rep..high.rep).map(|i| $name::new(i))
480 }
481
482 }
483
484 impl $crate::NumericId for $name {
485 type Rep = $repr;
486 type Atomic = $crate::atomic_of!($repr);
487 fn new(id: $repr) -> Self {
488 Self::new_const(id)
489 }
490 fn from_usize(index: usize) -> Self {
491 assert!(<$repr>::MAX as usize >= index,
492 "overflowing id type {} (represented as {}) with index {}", stringify!($name), stringify!($repr), index);
493 $name::new(index as $repr)
494 }
495 fn index(self) -> usize {
497 self.rep as usize
498 }
499 fn rep(self) -> $repr {
501 self.rep
502 }
503 }
504
505 impl std::fmt::Debug for $name {
506 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
507 write!(fmt, "{}({:?})", stringify!($name), self.rep)
508 }
509 }
510 };
511}