orx_split_vec/growth/
par_growth.rs

1use crate::{Doubling, Growth, GrowthWithConstantTimeAccess, Linear, Recursive};
2use orx_concurrent_iter::implementations::jagged_arrays::{
3    AsRawSlice, JaggedIndex, JaggedIndexer, Slices,
4};
5
6/// A [`Growth`] that supports parallelization.
7///
8/// All types implementing both [`Growth`] and [`JaggedIndexer`] implement [`ParGrowth`].
9///
10/// [`Doubling`], [`Linear`] and [`Recursive`] growth strategies all support parallel growth.
11///
12/// [`Doubling`]: crate::Doubling
13/// [`Linear`]: crate::Linear
14/// [`Recursive`]: crate::Recursive
15pub trait ParGrowth: Growth + JaggedIndexer {}
16
17impl<G: Growth + JaggedIndexer> ParGrowth for G {}
18
19impl JaggedIndexer for Doubling {
20    unsafe fn jagged_index_unchecked<'a, T: 'a>(
21        &self,
22        _: &impl Slices<'a, T>,
23        flat_index: usize,
24    ) -> JaggedIndex {
25        self.get_fragment_and_inner_indices_unchecked(flat_index)
26            .into()
27    }
28
29    unsafe fn jagged_index_unchecked_from_slice<'a, T: 'a>(
30        &self,
31        _: &[impl AsRawSlice<T>],
32        flat_index: usize,
33    ) -> JaggedIndex {
34        self.get_fragment_and_inner_indices_unchecked(flat_index)
35            .into()
36    }
37}
38
39impl JaggedIndexer for Linear {
40    unsafe fn jagged_index_unchecked<'a, T: 'a>(
41        &self,
42        _: &impl Slices<'a, T>,
43        flat_index: usize,
44    ) -> JaggedIndex {
45        self.get_fragment_and_inner_indices_unchecked(flat_index)
46            .into()
47    }
48
49    unsafe fn jagged_index_unchecked_from_slice<'a, T: 'a>(
50        &self,
51        _: &[impl AsRawSlice<T>],
52        flat_index: usize,
53    ) -> JaggedIndex {
54        self.get_fragment_and_inner_indices_unchecked(flat_index)
55            .into()
56    }
57}
58
59impl JaggedIndexer for Recursive {
60    unsafe fn jagged_index_unchecked<'a, T: 'a>(
61        &self,
62        arrays: &impl Slices<'a, T>,
63        flat_index: usize,
64    ) -> JaggedIndex {
65        let mut idx = flat_index;
66        let [mut f, mut i] = [0, 0];
67        let mut current_f = 0;
68        while idx > 0 {
69            let current_len = unsafe { arrays.slice_at_unchecked(current_f) }.len();
70            match current_len > idx {
71                true => {
72                    i = idx;
73                    idx = 0;
74                }
75                false => {
76                    f += 1;
77                    idx -= current_len;
78                }
79            }
80            current_f += 1;
81        }
82        JaggedIndex::new(f, i)
83    }
84
85    unsafe fn jagged_index_unchecked_from_slice<'a, T: 'a>(
86        &self,
87        arrays: &[impl AsRawSlice<T>],
88        flat_index: usize,
89    ) -> JaggedIndex {
90        let mut idx = flat_index;
91        let [mut f, mut i] = [0, 0];
92        let mut current_f = 0;
93        while idx > 0 {
94            let current_len = arrays[current_f].length();
95            match current_len > idx {
96                true => {
97                    i = idx;
98                    idx = 0;
99                }
100                false => {
101                    f += 1;
102                    idx -= current_len;
103                }
104            }
105            current_f += 1;
106        }
107        JaggedIndex::new(f, i)
108    }
109}