parallel_disk_usage/data_tree/reflection/
par_methods.rs1use super::{ConversionError, Reflection};
2use crate::{data_tree::DataTree, size};
3use rayon::prelude::*;
4use std::{ffi::OsStr, iter::once};
5
6impl<Name, Size> Reflection<Name, Size>
7where
8 Name: Send,
9 Size: size::Size + Send,
10{
11 pub fn par_try_into_tree(self) -> Result<DataTree<Name, Size>, ConversionError<Name, Size>> {
13 let Reflection {
14 name,
15 size,
16 children,
17 } = self;
18 let children_sum = children.iter().map(|child| child.size).sum();
19 if size < children_sum {
20 return Err(ConversionError::ExcessiveChildren {
21 path: once(name).collect(),
22 size,
23 children,
24 children_sum,
25 });
26 }
27 let children: Result<Vec<_>, _> = children
28 .into_par_iter()
29 .map(Self::par_try_into_tree)
30 .collect();
31 let children = match children {
32 Ok(children) => children,
33 Err(ConversionError::ExcessiveChildren {
34 mut path,
35 size,
36 children,
37 children_sum,
38 }) => {
39 path.push_front(name);
40 return Err(ConversionError::ExcessiveChildren {
41 path,
42 size,
43 children,
44 children_sum,
45 });
46 }
47 };
48 Ok(DataTree {
49 name,
50 size,
51 children,
52 })
53 }
54
55 pub fn par_try_map<TargetName, TargetSize, Error, Transform>(
57 self,
58 transform: Transform,
59 ) -> Result<Reflection<TargetName, TargetSize>, Error>
60 where
61 TargetName: Send,
62 TargetSize: size::Size + Send + Sync,
63 Error: Send,
64 Transform: Fn(Name, Size) -> Result<(TargetName, TargetSize), Error> + Copy + Sync,
65 {
66 let Reflection {
67 name,
68 size,
69 children,
70 } = self;
71 let children = children
72 .into_par_iter()
73 .map(|child| child.par_try_map(transform))
74 .collect::<Result<Vec<_>, _>>()?;
75 let (name, size) = transform(name, size)?;
76 Ok(Reflection {
77 name,
78 size,
79 children,
80 })
81 }
82
83 pub fn par_convert_names_to_utf8(self) -> Result<Reflection<String, Size>, Name>
85 where
86 Name: AsRef<OsStr>,
87 Size: Sync,
88 {
89 self.par_try_map(|name, size| {
90 name.as_ref()
91 .to_str()
92 .map(|name| (name.to_string(), size))
93 .ok_or(name)
94 })
95 }
96}