Skip to main content

veilid_tools/
hash_atom.rs

1use std::marker::PhantomData;
2
3use super::*;
4
5/// Pointer-identity hashing for unique objects
6/// Considers the `===` identity equals rather than the `==` Eq/PartialEq equals for objects
7/// that are guaranteed to be fixed in memory
8pub struct HashAtom<'a, T> {
9    val: usize,
10    is_arc: bool,
11    _phantom: &'a PhantomData<T>,
12}
13
14impl<T> Drop for HashAtom<'_, T> {
15    fn drop(&mut self) {
16        if self.is_arc {
17            unsafe {
18                let ptr = self.val as *const T;
19                Arc::from_raw(ptr);
20            };
21        }
22    }
23}
24
25impl<T> core::fmt::Debug for HashAtom<'_, T>
26where
27    T: fmt::Debug,
28{
29    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30        f.debug_struct("HashAtom").field("val", &self.val).finish()
31    }
32}
33
34impl<'a, T> From<Pin<&'a T>> for HashAtom<'a, T> {
35    fn from(value: Pin<&'a T>) -> Self {
36        Self {
37            val: (value.get_ref() as *const T) as usize,
38            is_arc: false,
39            _phantom: &PhantomData {},
40        }
41    }
42}
43
44impl<'a, T> From<Pin<&'a mut T>> for HashAtom<'a, T> {
45    fn from(value: Pin<&'a mut T>) -> Self {
46        Self {
47            val: (value.as_ref().get_ref() as *const T) as usize,
48            is_arc: false,
49            _phantom: &PhantomData {},
50        }
51    }
52}
53
54impl<T> From<Arc<T>> for HashAtom<'_, T> {
55    fn from(value: Arc<T>) -> Self {
56        let val = {
57            let ptr = Arc::into_raw(value);
58            ptr as usize
59        };
60        Self {
61            val,
62            is_arc: true,
63            _phantom: &PhantomData {},
64        }
65    }
66}
67
68impl<T> PartialEq for HashAtom<'_, T> {
69    fn eq(&self, other: &Self) -> bool {
70        self.val == other.val
71    }
72}
73
74impl<T> Eq for HashAtom<'_, T> {}
75
76impl<T> core::hash::Hash for HashAtom<'_, T> {
77    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
78        self.val.hash(state);
79    }
80}