asparit/core/setup.rs
1use std::cmp::{max, min};
2
3pub trait WithSetup {
4 /// Setup to drive the iterator with.
5 fn setup(&self) -> Setup {
6 Setup::default()
7 }
8}
9
10#[derive(Debug, Default, Clone)]
11pub struct Setup {
12 /// Number of splits/threads this iterator will use to proceed.
13 pub splits: Option<usize>,
14
15 /// The minimum number of items that we will process
16 /// sequentially. Defaults to 1, which means that we will split
17 /// all the way down to a single item. This can be raised higher
18 /// using the [`with_min_len`] method, which will force us to
19 /// create sequential tasks at a larger granularity. Note that
20 /// Rayon automatically normally attempts to adjust the size of
21 /// parallel splits to reduce overhead, so this should not be
22 /// needed.
23 ///
24 /// [`with_min_len`]: ../trait.IndexedParallelIterator.html#method.with_min_len
25 pub min_len: Option<usize>,
26
27 /// The maximum number of items that we will process
28 /// sequentially. Defaults to MAX, which means that we can choose
29 /// not to split at all. This can be lowered using the
30 /// [`with_max_len`] method, which will force us to create more
31 /// parallel tasks. Note that Rayon automatically normally
32 /// attempts to adjust the size of parallel splits to reduce
33 /// overhead, so this should not be needed.
34 ///
35 /// [`with_max_len`]: ../trait.IndexedParallelIterator.html#method.with_max_len
36 pub max_len: Option<usize>,
37}
38
39impl Setup {
40 pub fn merge(mut self, other: Self) -> Self {
41 self.splits = other.splits.or(self.splits);
42
43 self.min_len = match (self.min_len, other.min_len) {
44 (Some(a), Some(b)) => Some(max(a, b)),
45 (Some(a), None) => Some(a),
46 (None, Some(b)) => Some(b),
47 (None, None) => None,
48 };
49
50 self.max_len = match (self.max_len, other.max_len) {
51 (Some(a), Some(b)) => Some(min(a, b)),
52 (Some(a), None) => Some(a),
53 (None, Some(b)) => Some(b),
54 (None, None) => None,
55 };
56
57 self
58 }
59}