orx_fixed_vec/
concurrent_pinned_vec.rs

1use crate::{
2    FixedVec,
3    helpers::range::{range_end, range_start},
4};
5use alloc::vec::Vec;
6use core::cmp::Ordering;
7use core::fmt::Debug;
8use orx_pinned_vec::{ConcurrentPinnedVec, PinnedVecGrowthError};
9
10/// Concurrent wrapper ([`orx_pinned_vec::ConcurrentPinnedVec`]) for the `FixedVec`.
11pub struct ConcurrentFixedVec<T> {
12    data: Vec<T>,
13    ptr: *const T,
14    current_capacity: usize,
15}
16
17impl<T> Debug for ConcurrentFixedVec<T> {
18    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19        f.debug_struct("ConcurrentFixedVec")
20            .field("fixed_capacity", &self.current_capacity)
21            .finish()
22    }
23}
24
25impl<T> From<FixedVec<T>> for ConcurrentFixedVec<T> {
26    fn from(value: FixedVec<T>) -> Self {
27        let mut data = value.data;
28        let current_capacity = data.capacity();
29        unsafe { data.set_len(current_capacity) };
30        let ptr = data.as_mut_ptr();
31        Self {
32            data,
33            ptr,
34            current_capacity,
35        }
36    }
37}
38
39impl<T> ConcurrentPinnedVec<T> for ConcurrentFixedVec<T> {
40    type P = FixedVec<T>;
41
42    type SliceIter<'a>
43        = Option<&'a [T]>
44    where
45        T: 'a,
46        Self: 'a;
47
48    type SliceMutIter<'a>
49        = Option<&'a mut [T]>
50    where
51        T: 'a,
52        Self: 'a;
53
54    unsafe fn into_inner(mut self, len: usize) -> Self::P {
55        unsafe { self.data.set_len(len) };
56        self.data.into()
57    }
58
59    unsafe fn clone_with_len(&self, len: usize) -> Self
60    where
61        T: Clone,
62    {
63        assert!(len <= self.capacity());
64        let mut clone = Vec::with_capacity(self.capacity());
65        for i in 0..len {
66            clone.push(self.data[i].clone());
67        }
68        FixedVec::from(clone).into()
69    }
70
71    fn capacity(&self) -> usize {
72        self.current_capacity
73    }
74
75    fn max_capacity(&self) -> usize {
76        self.current_capacity
77    }
78
79    fn grow_to(&self, new_capacity: usize) -> Result<usize, PinnedVecGrowthError> {
80        match new_capacity <= self.capacity() {
81            true => Ok(self.capacity()),
82            false => Err(PinnedVecGrowthError::FailedToGrowWhileKeepingElementsPinned),
83        }
84    }
85
86    fn grow_to_and_fill_with<F>(
87        &self,
88        new_capacity: usize,
89        _: F,
90    ) -> Result<usize, PinnedVecGrowthError>
91    where
92        F: Fn() -> T,
93    {
94        match new_capacity <= self.capacity() {
95            true => Ok(self.capacity()),
96            false => Err(PinnedVecGrowthError::FailedToGrowWhileKeepingElementsPinned),
97        }
98    }
99
100    fn fill_with<F>(&self, range: core::ops::Range<usize>, fill_with: F)
101    where
102        F: Fn() -> T,
103    {
104        for i in range {
105            unsafe { self.get_ptr_mut(i).write(fill_with()) };
106        }
107    }
108
109    fn slices<R: core::ops::RangeBounds<usize>>(
110        &self,
111        range: R,
112    ) -> <Self::P as orx_pinned_vec::PinnedVec<T>>::SliceIter<'_> {
113        let a = range_start(&range);
114        let b = range_end(&range, self.capacity());
115
116        match b.saturating_sub(a) {
117            0 => Some(&[]),
118            _ => match (a.cmp(&self.capacity()), b.cmp(&self.capacity())) {
119                (Ordering::Equal | Ordering::Greater, _) => None,
120                (_, Ordering::Greater) => None,
121                _ => {
122                    let p = unsafe { self.ptr.add(a) };
123                    let slice = unsafe { core::slice::from_raw_parts(p, b - a) };
124                    Some(slice)
125                }
126            },
127        }
128    }
129
130    unsafe fn slices_mut<R: core::ops::RangeBounds<usize>>(
131        &self,
132        range: R,
133    ) -> <Self::P as orx_pinned_vec::PinnedVec<T>>::SliceMutIter<'_> {
134        let a = range_start(&range);
135        let b = range_end(&range, self.capacity());
136
137        match b.saturating_sub(a) {
138            0 => Some(&mut []),
139            _ => match (a.cmp(&self.capacity()), b.cmp(&self.capacity())) {
140                (Ordering::Equal | Ordering::Greater, _) => None,
141                (_, Ordering::Greater) => None,
142                _ => {
143                    let p = unsafe { self.ptr.add(a) };
144                    let slice = unsafe { core::slice::from_raw_parts_mut(p as *mut T, b - a) };
145                    Some(slice)
146                }
147            },
148        }
149    }
150
151    unsafe fn iter<'a>(&'a self, len: usize) -> impl Iterator<Item = &'a T> + 'a
152    where
153        T: 'a,
154    {
155        let p = self.data.as_ptr();
156        let slice = unsafe { core::slice::from_raw_parts(p, len) };
157        slice.iter()
158    }
159
160    unsafe fn iter_over_range<'a, R: core::ops::RangeBounds<usize>>(
161        &'a self,
162        range: R,
163    ) -> impl Iterator<Item = &'a T> + 'a
164    where
165        T: 'a,
166    {
167        let [a, b] = orx_pinned_vec::utils::slice::vec_range_limits(&range, None);
168        let len = b - a;
169        let p = unsafe { self.data.as_ptr().add(a) };
170        let slice = unsafe { core::slice::from_raw_parts(p, len) };
171        slice.iter()
172    }
173
174    unsafe fn iter_mut<'a>(&'a mut self, len: usize) -> impl Iterator<Item = &'a mut T> + 'a
175    where
176        T: 'a,
177    {
178        let p = self.data.as_mut_ptr();
179        let slice = unsafe { core::slice::from_raw_parts_mut(p, len) };
180        slice.iter_mut()
181    }
182
183    unsafe fn set_pinned_vec_len(&mut self, len: usize) {
184        unsafe { self.data.set_len(len) };
185    }
186
187    unsafe fn get(&self, index: usize) -> Option<&T> {
188        match index < self.capacity() {
189            true => Some(unsafe { &*self.ptr.add(index) }),
190            false => None,
191        }
192    }
193
194    unsafe fn get_mut(&mut self, index: usize) -> Option<&mut T> {
195        match index < self.capacity() {
196            true => Some(&mut self.data[index]),
197            false => None,
198        }
199    }
200
201    unsafe fn get_ptr_mut(&self, index: usize) -> *mut T {
202        assert!(index < self.capacity());
203        unsafe { self.ptr.add(index) as *mut T }
204    }
205
206    unsafe fn reserve_maximum_concurrent_capacity(
207        &mut self,
208        _: usize,
209        new_maximum_capacity: usize,
210    ) -> usize {
211        let additional = new_maximum_capacity.saturating_sub(self.capacity());
212        self.data.reserve(additional);
213
214        let new_capacity = self.data.capacity();
215        self.current_capacity = new_capacity;
216
217        new_capacity
218    }
219
220    unsafe fn reserve_maximum_concurrent_capacity_fill_with<F>(
221        &mut self,
222        current_len: usize,
223        new_maximum_capacity: usize,
224        fill_with: F,
225    ) -> usize
226    where
227        F: Fn() -> T,
228    {
229        let additional = new_maximum_capacity.saturating_sub(self.capacity());
230        self.data.reserve(additional);
231
232        self.current_capacity = self.data.capacity();
233
234        unsafe { self.data.set_len(current_len) };
235
236        for _ in current_len..self.current_capacity {
237            self.data.push(fill_with());
238        }
239
240        self.current_capacity
241    }
242
243    unsafe fn clear(&mut self, prior_len: usize) {
244        unsafe { self.set_pinned_vec_len(prior_len) };
245        self.data.clear()
246    }
247}