Skip to main content

asparit/executor/
misc.rs

1use std::cmp;
2
3/* Splitter */
4
5#[derive(Clone, Copy, Debug)]
6pub struct Splitter {
7    splits: usize,
8}
9
10impl Splitter {
11    #[inline]
12    pub fn new(splits: usize) -> Self {
13        Self { splits }
14    }
15
16    #[inline]
17    pub fn try_split(&mut self) -> bool {
18        if self.splits > 1 {
19            self.splits /= 2;
20
21            true
22        } else {
23            false
24        }
25    }
26}
27
28/* IndexedSplitter */
29
30#[derive(Clone, Copy, Debug)]
31pub struct IndexedSplitter {
32    inner: Splitter,
33    min: usize,
34}
35
36impl IndexedSplitter {
37    #[inline]
38    pub fn new(splits: usize, len: usize, min: Option<usize>, max: Option<usize>) -> Self {
39        let min = min.unwrap_or_default();
40        let mut ret = Self {
41            inner: Splitter::new(splits),
42            min: cmp::max(min, 1),
43        };
44
45        if let Some(max) = max {
46            let mut min_splits = len / cmp::max(max, 1);
47
48            // Calculate next Power of Two
49            min_splits -= 1;
50            min_splits |= min_splits >> 1;
51            min_splits |= min_splits >> 2;
52            min_splits |= min_splits >> 4;
53            min_splits |= min_splits >> 8;
54            min_splits |= min_splits >> 16;
55            min_splits += 1;
56
57            if min_splits > ret.inner.splits {
58                ret.inner.splits = min_splits;
59            }
60        }
61
62        ret
63    }
64
65    #[inline]
66    pub fn try_split(&mut self, len: usize) -> bool {
67        len / 2 >= self.min && self.inner.try_split()
68    }
69}