mod sum_computation;
use {
crate::{
app::*,
task_sync::Dam,
},
ahash::AHashMap,
once_cell::sync::Lazy,
std::{
ops::AddAssign,
path::{Path, PathBuf},
sync::Mutex,
},
};
pub const DEFAULT_THREAD_COUNT: usize = 5;
static SUM_CACHE: Lazy<Mutex<AHashMap<PathBuf, FileSum>>> = Lazy::new(|| {
Mutex::new(AHashMap::default())
});
pub fn clear_cache() {
SUM_CACHE.lock().unwrap().clear();
}
#[derive(Debug, Copy, Clone)]
pub struct FileSum {
real_size: u64, count: usize, modified: u32, sparse: bool, }
impl FileSum {
pub fn new(
real_size: u64,
sparse: bool,
count: usize,
modified: u32,
) -> Self {
Self { real_size, count, modified, sparse }
}
pub fn zero() -> Self {
Self::new(0, false, 0, 0)
}
pub fn incr(&mut self) {
self.count += 1;
}
pub fn from_file(path: &Path) -> Self {
sum_computation::compute_file_sum(path)
}
pub fn from_dir(path: &Path, dam: &Dam, con: &AppContext) -> Option<Self> {
let mut sum_cache = SUM_CACHE.lock().unwrap();
match sum_cache.get(path) {
Some(sum) => Some(*sum),
None => {
let sum = time!(
"sum computation",
path,
sum_computation::compute_dir_sum(path, &mut sum_cache, dam, con),
);
if let Some(sum) = sum {
sum_cache.insert(PathBuf::from(path), sum);
}
sum
}
}
}
pub fn part_of_size(self, total: Self) -> f32 {
if total.real_size == 0 {
0.0
} else {
self.real_size as f32 / total.real_size as f32
}
}
pub fn to_count(self) -> usize {
self.count
}
pub fn to_seconds(self) -> u32 {
self.modified
}
pub fn to_size(self) -> u64 {
self.real_size
}
pub fn to_valid_seconds(self) -> Option<i64> {
if self.modified != 0 {
Some(self.modified as i64)
} else {
None
}
}
pub fn is_sparse(self) -> bool {
self.sparse
}
}
impl AddAssign for FileSum {
#[allow(clippy::suspicious_op_assign_impl)]
fn add_assign(&mut self, other: Self) {
*self = Self::new(
self.real_size + other.real_size,
self.sparse | other.sparse,
self.count + other.count,
self.modified.max(other.modified),
);
}
}