orx_fixed_vec/
concurrent_pinned_vec.rs

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