granite_reckoner/
tools.rs

1use std::{
2    cmp,
3    fmt::{self, Debug, Formatter},
4};
5
6use crate::{Column, NumericType};
7
8pub fn calculate_ranges(data_size: usize, number_of_nodes: usize) -> Vec<(usize, usize)> {
9    let mut ranges: Vec<(usize, usize)> = vec![];
10    let length: usize = data_size / number_of_nodes;
11    let mut remain: usize = data_size % number_of_nodes;
12
13    let mut begin: usize = 0;
14    let mut end: usize = 0;
15
16    for _ in 0..cmp::min(data_size, number_of_nodes) {
17        end += if remain > 0 {
18            length + (remain > 0) as usize
19        } else {
20            length
21        };
22        if remain > 0 {
23            remain -= 1
24        };
25        ranges.push((begin, end));
26        begin = end;
27    }
28
29    ranges
30}
31
32pub fn partial_min<T: PartialOrd>(a: T, b: T) -> Option<T> {
33    if let Some(ordering) = a.partial_cmp(&b) {
34        match ordering {
35            std::cmp::Ordering::Less | std::cmp::Ordering::Equal => Some(a),
36            std::cmp::Ordering::Greater => Some(b),
37        }
38    } else {
39        None
40    }
41}
42
43pub fn partial_max<T: PartialOrd>(a: T, b: T) -> Option<T> {
44    if let Some(ordering) = a.partial_cmp(&b) {
45        match ordering {
46            std::cmp::Ordering::Less | std::cmp::Ordering::Equal => Some(b),
47            std::cmp::Ordering::Greater => Some(a),
48        }
49    } else {
50        None
51    }
52}
53
54impl<T: NumericType<T>> Debug for Column<T> {
55    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
56        let inner_data = self.data.data();
57        for idx in 0..inner_data.len() - 1 {
58            write!(f, "{}\n", inner_data[idx])?;
59        }
60        write!(f, "{}", inner_data[inner_data.len() - 1])?;
61
62        Ok(())
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    #[test]
70    fn test_ranges_1_works() {
71        let ranges = calculate_ranges(10, 4);
72        assert_eq!(ranges[0], (0, 3));
73        assert_eq!(ranges[1], (3, 6));
74        assert_eq!(ranges[2], (6, 8));
75        assert_eq!(ranges[3], (8, 10));
76    }
77    #[test]
78    fn test_ranges_2_works() {
79        let ranges = calculate_ranges(30, 5);
80        assert_eq!(ranges[0], (0, 6));
81        assert_eq!(ranges[1], (6, 12));
82        assert_eq!(ranges[2], (12, 18));
83        assert_eq!(ranges[3], (18, 24));
84        assert_eq!(ranges[4], (24, 30));
85    }
86    #[test]
87    fn test_ranges_3_works() {
88        let ranges = calculate_ranges(11, 4);
89        assert_eq!(ranges[0], (0, 3));
90        assert_eq!(ranges[1], (3, 6));
91        assert_eq!(ranges[2], (6, 9));
92        assert_eq!(ranges[3], (9, 11));
93    }
94    #[test]
95    fn test_ranges_4_works() {
96        let ranges = calculate_ranges(3, 4);
97        assert_eq!(ranges[0], (0, 1));
98        assert_eq!(ranges[1], (1, 2));
99        assert_eq!(ranges[2], (2, 3));
100    }
101    #[test]
102    fn test_ranges_5_works() {
103        let ranges = calculate_ranges(5, 3);
104        assert_eq!(ranges[0], (0, 2));
105        assert_eq!(ranges[1], (2, 4));
106        assert_eq!(ranges[2], (4, 5));
107    }
108}