-
-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathhardlink.rs
More file actions
46 lines (42 loc) · 1.53 KB
/
hardlink.rs
File metadata and controls
46 lines (42 loc) · 1.53 KB
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
use super::DataTree;
use crate::size;
use assert_cmp::debug_assert_op;
use orx_parallel::*;
use std::{ffi::OsStr, path::Path};
impl<Name, Size> DataTree<Name, Size>
where
Self: Send + Sync,
Name: AsRef<OsStr>,
Size: size::Size + Sync,
{
/// Reduce the size of the directories that have hardlinks.
#[cfg_attr(not(unix), expect(unused))]
pub(crate) fn par_deduplicate_hardlinks(&mut self, hardlink_info: &[(Size, Vec<&Path>)]) {
if hardlink_info.is_empty() {
return;
}
let prefix = self.name().as_ref();
let sub_hardlink_info: Vec<(Size, Vec<&Path>)> = hardlink_info
.iter()
.filter(|(_, link_paths)| link_paths.len() > 1)
.map(|(size, link_paths)| {
let link_suffices: Vec<&Path> = link_paths
.iter()
.map(|link_path| link_path.strip_prefix(prefix))
.filter_map(Result::ok)
.collect();
(*size, link_suffices)
})
.filter(|(_, link_paths)| link_paths.len() > 1)
.collect();
for (size, link_suffices) in &sub_hardlink_info {
let number_of_links = link_suffices.len();
debug_assert_op!(number_of_links > 1);
self.size -= *size * (number_of_links - 1);
}
self.children
.iter_mut() // TODO: request orx-parallel to add par_mut
.iter_into_par()
.for_each(|child| child.par_deduplicate_hardlinks(&sub_hardlink_info))
}
}