orx_fixed_vec/
concurrent_pinned_vec.rs

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