|
1 | 1 | use crate::{
|
2 |
| - common_traits::iterator::iter_con::IterCon, |
3 | 2 | fragment::fragment_struct::{
|
4 | 3 | maximum_concurrent_capacity, num_fragments_for_capacity, set_fragments_len,
|
5 | 4 | },
|
@@ -44,7 +43,7 @@ impl<T, G: GrowthWithConstantTimeAccess> Drop for ConcurrentSplitVec<T, G> {
|
44 | 43 |
|
45 | 44 | impl<T, G: GrowthWithConstantTimeAccess> ConcurrentSplitVec<T, G> {
|
46 | 45 | fn num_fragments(&self) -> usize {
|
47 |
| - self.num_fragments.load(Ordering::Relaxed) |
| 46 | + self.num_fragments.load(Ordering::SeqCst) |
48 | 47 | }
|
49 | 48 |
|
50 | 49 | fn fragments(&self) -> &[Fragment<T>] {
|
@@ -124,6 +123,7 @@ impl<T, G: GrowthWithConstantTimeAccess> ConcurrentPinnedVec<T> for ConcurrentSp
|
124 | 123 | let growth = self.growth.clone();
|
125 | 124 |
|
126 | 125 | // let (mut fragments, growth) = (self.fragments, self.growth.clone());
|
| 126 | + |
127 | 127 | SplitVec::from_raw_parts(len, fragments, growth)
|
128 | 128 | }
|
129 | 129 |
|
@@ -164,6 +164,94 @@ impl<T, G: GrowthWithConstantTimeAccess> ConcurrentPinnedVec<T> for ConcurrentSp
|
164 | 164 | }
|
165 | 165 | }
|
166 | 166 |
|
| 167 | + fn grow_to_and_fill_with<F>( |
| 168 | + &self, |
| 169 | + new_capacity: usize, |
| 170 | + fill_with: F, |
| 171 | + ) -> Result<usize, orx_pinned_vec::PinnedVecGrowthError> |
| 172 | + where |
| 173 | + F: Fn() -> T, |
| 174 | + { |
| 175 | + let capacity = self.capacity(); |
| 176 | + match new_capacity <= capacity { |
| 177 | + true => Ok(capacity), |
| 178 | + false => { |
| 179 | + let mut num_fragments = self.num_fragments(); |
| 180 | + |
| 181 | + let mut current_capacity = capacity; |
| 182 | + |
| 183 | + while new_capacity > current_capacity { |
| 184 | + let new_fragment_capacity = self |
| 185 | + .growth |
| 186 | + .new_fragment_capacity(self.fragments_for(num_fragments)); |
| 187 | + let mut new_fragment = Fragment::<T>::new(new_fragment_capacity); |
| 188 | + for _ in 0..new_fragment_capacity { |
| 189 | + new_fragment.push(fill_with()); |
| 190 | + } |
| 191 | + |
| 192 | + self.push_fragment(new_fragment, num_fragments); |
| 193 | + |
| 194 | + num_fragments += 1; |
| 195 | + current_capacity += new_fragment_capacity; |
| 196 | + } |
| 197 | + |
| 198 | + self.num_fragments.store(num_fragments, Ordering::SeqCst); |
| 199 | + self.capacity.store(current_capacity, Ordering::SeqCst); |
| 200 | + |
| 201 | + Ok(current_capacity) |
| 202 | + } |
| 203 | + } |
| 204 | + } |
| 205 | + |
| 206 | + fn slices<R: RangeBounds<usize>>(&self, range: R) -> <Self::P as PinnedVec<T>>::SliceIter<'_> { |
| 207 | + use std::slice::from_raw_parts; |
| 208 | + |
| 209 | + let fragments = self.fragments(); |
| 210 | + let fragment_and_inner_indices = |
| 211 | + |i| self.growth.get_fragment_and_inner_indices_unchecked(i); |
| 212 | + |
| 213 | + let a = range_start(&range); |
| 214 | + let b = range_end(&range, self.capacity()); |
| 215 | + |
| 216 | + match b.saturating_sub(a) { |
| 217 | + 0 => vec![], |
| 218 | + _ => { |
| 219 | + let (sf, si) = fragment_and_inner_indices(a); |
| 220 | + let (ef, ei) = fragment_and_inner_indices(b - 1); |
| 221 | + |
| 222 | + match sf == ef { |
| 223 | + true => { |
| 224 | + let p = self.fragment_element_ptr_mut(sf, si); |
| 225 | + let slice = unsafe { from_raw_parts(p, ei - si + 1) }; |
| 226 | + vec![slice] |
| 227 | + } |
| 228 | + false => { |
| 229 | + let mut vec = Vec::with_capacity(ef - sf + 1); |
| 230 | + |
| 231 | + let slice_len = fragments[sf].capacity() - si; |
| 232 | + let ptr_s = self.fragment_element_ptr_mut(sf, si); |
| 233 | + let slice = unsafe { from_raw_parts(ptr_s, slice_len) }; |
| 234 | + vec.push(slice); |
| 235 | + |
| 236 | + for (f, fragment) in fragments.iter().enumerate().take(ef).skip(sf + 1) { |
| 237 | + let slice_len = fragment.capacity(); |
| 238 | + let ptr_s = self.fragment_element_ptr_mut(f, 0); |
| 239 | + let slice = unsafe { from_raw_parts(ptr_s, slice_len) }; |
| 240 | + vec.push(slice); |
| 241 | + } |
| 242 | + |
| 243 | + let slice_len = ei + 1; |
| 244 | + let ptr_s = self.fragment_element_ptr_mut(ef, 0); |
| 245 | + let slice = unsafe { from_raw_parts(ptr_s, slice_len) }; |
| 246 | + vec.push(slice); |
| 247 | + |
| 248 | + vec |
| 249 | + } |
| 250 | + } |
| 251 | + } |
| 252 | + } |
| 253 | + } |
| 254 | + |
167 | 255 | unsafe fn slices_mut<R: RangeBounds<usize>>(
|
168 | 256 | &self,
|
169 | 257 | range: R,
|
@@ -217,36 +305,62 @@ impl<T, G: GrowthWithConstantTimeAccess> ConcurrentPinnedVec<T> for ConcurrentSp
|
217 | 305 | where
|
218 | 306 | T: 'a,
|
219 | 307 | {
|
| 308 | + use std::slice::from_raw_parts; |
| 309 | + |
220 | 310 | let fragments = self.fragments();
|
221 | 311 |
|
222 |
| - match len { |
223 |
| - 0 => IterCon::new(&fragments[0..1], 0), |
| 312 | + let fragment_and_inner_indices = |
| 313 | + |i| self.growth.get_fragment_and_inner_indices_unchecked(i); |
| 314 | + |
| 315 | + let range = 0..len; |
| 316 | + |
| 317 | + let a = range_start(&range); |
| 318 | + let b = range_end(&range, self.capacity()); |
| 319 | + |
| 320 | + let x = match b.saturating_sub(a) { |
| 321 | + 0 => vec![], |
224 | 322 | _ => {
|
225 |
| - // let mut num_fragments = 0; |
226 |
| - let mut count = 0; |
227 |
| - |
228 |
| - for (num_fragments, fragment) in fragments.iter().enumerate() { |
229 |
| - // for fragment in fragments.iter() { |
230 |
| - // num_fragments += 1; |
231 |
| - let capacity = fragment.capacity(); |
232 |
| - let new_count = count + capacity; |
233 |
| - |
234 |
| - match new_count >= len { |
235 |
| - true => { |
236 |
| - let last_fragment_len = capacity - (new_count - len); |
237 |
| - return IterCon::new( |
238 |
| - &fragments[0..(num_fragments + 1)], |
239 |
| - last_fragment_len, |
240 |
| - ); |
| 323 | + let (sf, si) = fragment_and_inner_indices(a); |
| 324 | + let (ef, ei) = fragment_and_inner_indices(b - 1); |
| 325 | + |
| 326 | + match sf == ef { |
| 327 | + true => { |
| 328 | + let p = fragments[sf].as_ptr().add(si); |
| 329 | + let slice = from_raw_parts(p, ei - si + 1); |
| 330 | + vec![slice] |
| 331 | + } |
| 332 | + false => { |
| 333 | + let mut vec = Vec::with_capacity(ef - sf + 1); |
| 334 | + |
| 335 | + if let Some(first) = fragments.get(sf) { |
| 336 | + let slice_len = first.capacity() - si; |
| 337 | + |
| 338 | + let p = first.as_ptr().add(si); |
| 339 | + let slice = from_raw_parts(p, slice_len); |
| 340 | + vec.push(slice); |
| 341 | + } |
| 342 | + |
| 343 | + for fragment in fragments.iter().take(ef).skip(sf + 1) { |
| 344 | + let slice_len = fragment.capacity(); |
| 345 | + let p = fragment.as_ptr(); |
| 346 | + let slice = from_raw_parts(p, slice_len); |
| 347 | + vec.push(slice); |
| 348 | + } |
| 349 | + |
| 350 | + if let Some(last) = fragments.get(ef) { |
| 351 | + let slice_len = ei + 1; |
| 352 | + let p = last.as_ptr(); |
| 353 | + let slice = from_raw_parts(p, slice_len); |
| 354 | + vec.push(slice); |
241 | 355 | }
|
242 |
| - false => count = new_count, |
| 356 | + |
| 357 | + vec |
243 | 358 | }
|
244 | 359 | }
|
245 |
| - |
246 |
| - let last_fragment_len = fragments[fragments.len() - 1].capacity(); |
247 |
| - IterCon::new(fragments, last_fragment_len) |
248 | 360 | }
|
249 |
| - } |
| 361 | + }; |
| 362 | + |
| 363 | + x.into_iter().flat_map(|x| x.iter()) |
250 | 364 | }
|
251 | 365 |
|
252 | 366 | unsafe fn iter_mut<'a>(&'a mut self, len: usize) -> impl Iterator<Item = &'a mut T> + 'a
|
|
0 commit comments