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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use {
crate::task_sync::Dam,
std::{
collections::HashMap,
fmt,
ops::AddAssign,
path::{Path, PathBuf},
sync::Mutex,
},
};
const SIZE_NAMES: &[&str] = &["", "K", "M", "G", "T", "P", "E", "Z", "Y"];
lazy_static! {
static ref SIZE_CACHE_MUTEX: Mutex<HashMap<PathBuf, u64>> = Mutex::new(HashMap::new());
}
pub fn clear_cache() {
let mut size_cache = SIZE_CACHE_MUTEX.lock().unwrap();
size_cache.clear();
}
#[derive(Debug, Copy, Clone)]
pub struct FileSize {
real_size: u64,
pub sparse: bool,
}
impl FileSize {
pub fn new(real_size: u64, sparse: bool) -> Self {
Self { real_size, sparse }
}
pub fn from_file(path: &Path) -> Self {
compute_file_size(path)
}
pub fn from_dir(path: &Path, dam: &Dam) -> Option<Self> {
let mut size_cache = SIZE_CACHE_MUTEX.lock().unwrap();
if let Some(s) = size_cache.get(path) {
return Some(Self::new(*s, false));
}
if let Some(s) = time!(Debug, "size sum", path, compute_dir_size(path, dam)) {
size_cache.insert(PathBuf::from(path), s);
Some(FileSize::new(s, false))
} else {
None
}
}
pub fn part_of(self, total: Self) -> f32 {
if total.real_size == 0 {
0.0
} else {
self.real_size as f32 / total.real_size as f32
}
}
}
impl fmt::Display for FileSize {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut v = self.real_size;
let mut i = 0;
while v >= 5000 && i < SIZE_NAMES.len() - 1 {
v /= 1000;
i += 1;
}
write!(f, "{}{}", v, &SIZE_NAMES[i])
}
}
impl AddAssign for FileSize {
fn add_assign(&mut self, other: Self) {
*self = Self::new(
self.real_size + other.real_size,
self.sparse | other.sparse,
);
}
}
impl Into<u64> for FileSize {
fn into(self) -> u64 {
self.real_size
}
}
#[cfg(unix)]
mod file_sizes_unix;
#[cfg(unix)]
use file_sizes_unix::*;
#[cfg(not(unix))]
mod file_sizes_default;
#[cfg(not(unix))]
use file_sizes_default::*;