turbo_persistence/
arc_slice.rs

1use std::{
2    borrow::Borrow,
3    fmt::{self, Debug, Formatter},
4    hash::{Hash, Hasher},
5    ops::{Deref, Range},
6    sync::Arc,
7};
8
9/// A owned slice that is backed by an `Arc`.
10#[derive(Clone)]
11pub struct ArcSlice<T> {
12    data: *const [T],
13    arc: Arc<[T]>,
14}
15
16unsafe impl<T> Send for ArcSlice<T> {}
17unsafe impl<T> Sync for ArcSlice<T> {}
18
19impl<T> From<Arc<[T]>> for ArcSlice<T> {
20    fn from(arc: Arc<[T]>) -> Self {
21        Self {
22            data: &*arc as *const [T],
23            arc,
24        }
25    }
26}
27
28impl<T> From<Box<[T]>> for ArcSlice<T> {
29    fn from(b: Box<[T]>) -> Self {
30        Self::from(Arc::from(b))
31    }
32}
33
34impl<T> Deref for ArcSlice<T> {
35    type Target = [T];
36
37    fn deref(&self) -> &Self::Target {
38        unsafe { &*self.data }
39    }
40}
41
42impl<T> Borrow<[T]> for ArcSlice<T> {
43    fn borrow(&self) -> &[T] {
44        self
45    }
46}
47
48impl<T: Hash> Hash for ArcSlice<T> {
49    fn hash<H: Hasher>(&self, state: &mut H) {
50        self.deref().hash(state)
51    }
52}
53
54impl<T: PartialEq> PartialEq for ArcSlice<T> {
55    fn eq(&self, other: &Self) -> bool {
56        self.deref().eq(other.deref())
57    }
58}
59
60impl<T: Debug> Debug for ArcSlice<T> {
61    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
62        Debug::fmt(&**self, f)
63    }
64}
65
66impl<T: Eq> Eq for ArcSlice<T> {}
67
68impl<T> ArcSlice<T> {
69    /// Creates a new `ArcSlice` from a pointer to a slice and an `Arc`.
70    ///
71    /// # Safety
72    ///
73    /// The caller must ensure that the pointer is pointing to a valid slice that is kept alive by
74    /// the `Arc`.
75    pub unsafe fn new_unchecked(data: *const [T], arc: Arc<[T]>) -> Self {
76        Self { data, arc }
77    }
78
79    /// Get the backing arc
80    pub fn full_arc(this: &ArcSlice<T>) -> Arc<[T]> {
81        this.arc.clone()
82    }
83
84    /// Returns a new `ArcSlice` that points to a slice of the current slice.
85    pub fn slice(self, range: Range<usize>) -> ArcSlice<T> {
86        let data = &*self;
87        let data = &data[range] as *const [T];
88        Self {
89            data,
90            arc: self.arc,
91        }
92    }
93}