libdd_profiling/internal/profile/interning_api/
generational_ids.rs1use std::sync::atomic::AtomicU64;
5
6#[derive(Clone, Copy, PartialEq, Eq)]
8#[repr(C)]
9pub struct Generation {
10 id: u64,
11}
12
13impl Generation {
14 const IMMORTAL: Self = Self { id: u64::MAX };
15
16 pub fn new() -> Self {
18 static COUNTER: AtomicU64 = AtomicU64::new(0);
19 Self {
20 id: COUNTER.fetch_add(1, std::sync::atomic::Ordering::SeqCst),
21 }
22 }
23}
24impl Default for Generation {
25 fn default() -> Self {
26 Self::new()
27 }
28}
29
30#[repr(C)]
31pub struct GenerationalId<T: Copy> {
32 generation: Generation,
33 id: T,
34}
35
36impl<T: Copy> GenerationalId<T> {
37 pub fn get(&self, expected_generation: Generation) -> anyhow::Result<T> {
38 anyhow::ensure!(
39 self.generation == expected_generation || self.generation == Generation::IMMORTAL
40 );
41 Ok(self.id)
42 }
43
44 pub const fn new(id: T, generation: Generation) -> Self {
45 Self { id, generation }
46 }
47
48 pub const fn new_immortal(id: T) -> Self {
49 Self {
50 id,
51 generation: Generation::IMMORTAL,
52 }
53 }
54}