orx_fixed_vec/con_pinned_vec/
con_fixed_vec.rs

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