Skip to content

Commit 5d0b013

Browse files
authored
Merge pull request #49 from orxfun/fill-with-to-enable-concurrent-initialized-growth
fill with to enable concurrent initialized growth
2 parents 4fa7803 + 25592ac commit 5d0b013

File tree

9 files changed

+161
-139
lines changed

9 files changed

+161
-139
lines changed

Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "orx-split-vec"
3-
version = "3.2.0"
3+
version = "3.3.0"
44
edition = "2021"
55
authors = ["orxfun <[email protected]>"]
66
description = "An efficient constant access time vector with dynamic capacity and pinned elements."
@@ -10,8 +10,8 @@ keywords = ["vec", "array", "split", "fragments", "pinned"]
1010
categories = ["data-structures", "rust-patterns"]
1111

1212
[dependencies]
13-
orx-pseudo-default = "1.2.0"
14-
orx-pinned-vec = "3.2.0"
13+
orx-pseudo-default = "1.2"
14+
orx-pinned-vec = "3.3"
1515

1616
[[bench]]
1717
name = "serial_access"

src/common_traits/iterator/iter_con.rs

-69
This file was deleted.

src/common_traits/iterator/iter_fragment.rs

-35
This file was deleted.

src/common_traits/iterator/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ mod eq;
22
mod from_iter;
33
pub(crate) mod into_iter;
44
pub(crate) mod iter;
5-
pub(crate) mod iter_con;
6-
mod iter_fragment;
75
pub(crate) mod iter_mut;
86
pub(crate) mod iter_mut_rev;
97
pub(crate) mod iter_rev;

src/concurrent_pinned_vec.rs

+139-25
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::{
2-
common_traits::iterator::iter_con::IterCon,
32
fragment::fragment_struct::{
43
maximum_concurrent_capacity, num_fragments_for_capacity, set_fragments_len,
54
},
@@ -44,7 +43,7 @@ impl<T, G: GrowthWithConstantTimeAccess> Drop for ConcurrentSplitVec<T, G> {
4443

4544
impl<T, G: GrowthWithConstantTimeAccess> ConcurrentSplitVec<T, G> {
4645
fn num_fragments(&self) -> usize {
47-
self.num_fragments.load(Ordering::Relaxed)
46+
self.num_fragments.load(Ordering::SeqCst)
4847
}
4948

5049
fn fragments(&self) -> &[Fragment<T>] {
@@ -124,6 +123,7 @@ impl<T, G: GrowthWithConstantTimeAccess> ConcurrentPinnedVec<T> for ConcurrentSp
124123
let growth = self.growth.clone();
125124

126125
// let (mut fragments, growth) = (self.fragments, self.growth.clone());
126+
127127
SplitVec::from_raw_parts(len, fragments, growth)
128128
}
129129

@@ -164,6 +164,94 @@ impl<T, G: GrowthWithConstantTimeAccess> ConcurrentPinnedVec<T> for ConcurrentSp
164164
}
165165
}
166166

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+
167255
unsafe fn slices_mut<R: RangeBounds<usize>>(
168256
&self,
169257
range: R,
@@ -217,36 +305,62 @@ impl<T, G: GrowthWithConstantTimeAccess> ConcurrentPinnedVec<T> for ConcurrentSp
217305
where
218306
T: 'a,
219307
{
308+
use std::slice::from_raw_parts;
309+
220310
let fragments = self.fragments();
221311

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![],
224322
_ => {
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);
241355
}
242-
false => count = new_count,
356+
357+
vec
243358
}
244359
}
245-
246-
let last_fragment_len = fragments[fragments.len() - 1].capacity();
247-
IterCon::new(fragments, last_fragment_len)
248360
}
249-
}
361+
};
362+
363+
x.into_iter().flat_map(|x| x.iter())
250364
}
251365

252366
unsafe fn iter_mut<'a>(&'a mut self, len: usize) -> impl Iterator<Item = &'a mut T> + 'a

src/growth/doubling/doubling_growth.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ mod tests {
276276
let mut curr_capacity = 4;
277277
let mut cumulative_capacity = 4;
278278

279-
for index in 0..1111111 {
279+
for index in 0..51_111 {
280280
if index == cumulative_capacity {
281281
prev_cumulative_capacity = cumulative_capacity;
282282
curr_capacity *= 2;

src/growth/linear/linear_growth.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ mod tests {
262262
let mut prev_cumulative_capacity = 0;
263263
let mut cumulative_capacity = curr_capacity;
264264

265-
for index in 0..1111111 {
265+
for index in 0..51_111 {
266266
if index == cumulative_capacity {
267267
prev_cumulative_capacity = cumulative_capacity;
268268
cumulative_capacity += curr_capacity;

src/growth/recursive/recursive_growth.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,9 @@ mod tests {
249249

250250
let mut fragments: Vec<Fragment<_>> = vec![];
251251

252-
let lengths = [30, 52, 14, 1, 7, 3, 79, 248, 147, 530];
252+
let lengths = [30, 1, 7, 3, 79, 147, 530];
253253
let mut index = 0;
254-
for _ in 0..100 {
254+
for _ in 0..10 {
255255
for &len in &lengths {
256256
let mut vec = Vec::with_capacity(len);
257257
for _ in 0..len {
@@ -266,7 +266,7 @@ mod tests {
266266

267267
let mut index = 0;
268268
let mut f = 0;
269-
for _ in 0..100 {
269+
for _ in 0..10 {
270270
for &len in &lengths {
271271
for i in 0..len {
272272
let maybe_fi =

src/into_concurrent_pinned_vec.rs

+14
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,18 @@ impl<T, G: GrowthWithConstantTimeAccess> IntoConcurrentPinnedVec<T> for SplitVec
77
fn into_concurrent(self) -> Self::ConPinnedVec {
88
self.into()
99
}
10+
11+
fn into_concurrent_filled_with<F>(mut self, fill_with: F) -> Self::ConPinnedVec
12+
where
13+
F: Fn() -> T,
14+
{
15+
if let Some(fragment) = self.fragments.last_mut() {
16+
let (len, capacity) = (fragment.len(), fragment.capacity());
17+
for _ in len..capacity {
18+
fragment.push(fill_with());
19+
}
20+
}
21+
22+
self.into()
23+
}
1024
}

0 commit comments

Comments
 (0)