1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//! The MOC library contains the core functionalities to create and maniuplates MOCs.
//!
//! it is used in [MOCPy](https://github.com/cds-astro/mocpy),
//! [moc-cli](https://github.com/cds-astro/cds-moc-rust/tree/main/crates/cli) and
//! [moc-wasm](https://github.com/cds-astro/cds-moc-rust/tree/main/crates/wasm).
//!
//! The library is not (yet?) properly documented.
//! To use it, we so far recommend to look at the source code of the tools using it
//! (moc-wasm for example).
//!

#[cfg(not(target_arch = "wasm32"))]
use rayon::ThreadPoolBuildError;

pub mod idx;
pub mod qty;
pub mod elem;
pub mod elemset;
pub mod ranges;
pub mod moc;

pub mod mocranges2d;
pub mod hpxranges2d;
pub mod moc2d;

pub mod deser;

pub mod utils;
#[cfg(feature = "storage")]
pub mod storage;

// from_fits
// from_cone
// from_...

/// Init the number of threads for parallel tasks.
/// Must be called only once!
/// If not called, the default number of threads is the number of physical core.
/// See [rayon doc](https://docs.rs/rayon/1.5.1/rayon/struct.ThreadPoolBuilder.html)
#[cfg(not(target_arch = "wasm32"))]
pub fn init_par(num_threads: usize) -> Result<(), ThreadPoolBuildError> {
  rayon::ThreadPoolBuilder::new().num_threads(num_threads).build_global()
}

#[cfg(test)]
mod tests {
    use num::PrimInt;

    use crate::elemset::range::{
        HpxRanges,
        uniq::HpxUniqRanges
    };

    #[test]
    fn test_uniq_iter() {
        let simple_nested = HpxRanges::<u64>::new_unchecked(vec![0..1]);
        let complex_nested = HpxRanges::<u64>::new_unchecked(vec![7..76]);
        let empty_nested = HpxRanges::<u64>::default();

        let simple_uniq = HpxUniqRanges::<u64>::new_unchecked(vec![4 * 4.pow(29)..(4 * 4.pow(29) + 1)]);
        let complex_uniq = HpxUniqRanges::<u64>::new_from_sorted(vec![
            (1 + 4 * 4.pow(27))..(4 + 4 * 4.pow(27)),
            (2 + 4 * 4.pow(28))..(4 + 4 * 4.pow(28)),
            (16 + 4 * 4.pow(28))..(19 + 4 * 4.pow(28)),
            (7 + 4 * 4.pow(29))..(8 + 4 * 4.pow(29)),
        ]);
        let empty_uniq = HpxUniqRanges::<u64>::new_unchecked(vec![]);

        assert_eq!(simple_nested.clone().into_hpx_uniq(), simple_uniq);
        assert_eq!(complex_nested.clone().into_hpx_uniq(), complex_uniq);
        assert_eq!(empty_nested.clone().into_hpx_uniq(), empty_uniq);

        assert_eq!(simple_uniq.into_hpx(), simple_nested);
        assert_eq!(complex_uniq.into_hpx(), complex_nested);
        assert_eq!(empty_uniq.into_hpx(), empty_nested);
    }

    #[test]
    fn test_uniq_nested_conversion() {
        let input = vec![
            1056..1057,
            1057..1058,
            1083..1084,
            1048539..1048540,
            1048574..1048575,
            1048575..1048576,
        ];

        let ranges = HpxUniqRanges::<u64>::new_from_sorted(input.clone());
        let expected = HpxUniqRanges::<u64>::new_from_sorted(input);

        assert_eq!(ranges.into_hpx().into_hpx_uniq(), expected);
    }
}