orx_fixed_vec/
concurrent_pinned_vec.rs1use 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
10pub 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}