parallel_disk_usage/data_tree/
retain.rs

1use super::DataTree;
2use crate::size;
3use rayon::prelude::*;
4
5impl<Name, Size> DataTree<Name, Size>
6where
7    Self: Send,
8    Size: size::Size,
9{
10    /// Internal function to be used by [`Self::par_retain`].
11    fn par_retain_with_depth(
12        &mut self,
13        current_depth: u64,
14        predicate: impl Fn(&Self, u64) -> bool + Copy + Sync,
15    ) {
16        self.children
17            .retain(|child| predicate(child, current_depth));
18        let next_depth = current_depth + 1;
19        self.children
20            .par_iter_mut()
21            .for_each(|child| child.par_retain_with_depth(next_depth, predicate))
22    }
23
24    /// Recursively cull all descendants that do not satisfy given `predicate`, in parallel.
25    pub fn par_retain(&mut self, predicate: impl Fn(&Self, u64) -> bool + Copy + Sync) {
26        self.par_retain_with_depth(0, predicate)
27    }
28
29    /// Process the tree via [`par_retain`](Self::par_retain) method.
30    pub fn into_par_retained(
31        mut self,
32        predicate: impl Fn(&Self, u64) -> bool + Copy + Sync,
33    ) -> Self {
34        self.par_retain(predicate);
35        self
36    }
37
38    /// Recursively cull all descendants whose sizes are too small relative to root.
39    #[cfg(feature = "cli")]
40    pub fn par_cull_insignificant_data(&mut self, min_ratio: f32)
41    where
42        Size: Into<u64>,
43    {
44        let minimal = self.size().into() as f32 * min_ratio;
45        self.par_retain(|descendant, _| descendant.size().into() as f32 >= minimal);
46    }
47
48    /// Process the tree via [`par_cull_insignificant_data`](Self::par_cull_insignificant_data) method.
49    #[cfg(test)]
50    #[cfg(feature = "cli")]
51    fn into_insignificant_data_par_culled(mut self, min_ratio: f32) -> Self
52    where
53        Size: Into<u64>,
54    {
55        self.par_cull_insignificant_data(min_ratio);
56        self
57    }
58}
59
60#[cfg(test)]
61#[cfg(feature = "cli")]
62mod test;