1use std::path::PathBuf;
4use std::time::SystemTime;
5
6pub const CACHE_SUBDIRS: &[&str] = &[
8 "thumbnails",
9 "raw_decode",
10 "exif",
11 "video",
12 "preview",
13 "open-in",
14 "drag_export",
15];
16
17const YIELD_EVERY: usize = 64;
19
20fn cache_root() -> Option<PathBuf> {
21 crate::profile::cache_dir()
22}
23
24pub fn clear_all_blocking() -> Result<(), String> {
26 let Some(root) = cache_root() else {
27 return Ok(());
28 };
29 let mut first_error: Option<String> = None;
30 for sub in CACHE_SUBDIRS {
31 let dir = root.join(sub);
32 if !dir.exists() {
33 continue;
34 }
35 if let Err(err) = std::fs::remove_dir_all(&dir)
36 && first_error.is_none()
37 {
38 first_error = Some(format!("{}: {}", dir.display(), err));
39 }
40 }
41 match first_error {
42 Some(err) => Err(err),
43 None => Ok(()),
44 }
45}
46
47pub fn prune_all_blocking(cap_bytes: u64) {
49 let Some(root) = cache_root() else {
50 return;
51 };
52 let mut entries: Vec<(PathBuf, u64, SystemTime)> = Vec::new();
53 let mut total: u64 = 0;
54 for sub in CACHE_SUBDIRS {
55 collect_files(&root.join(sub), &mut entries, &mut total);
56 }
57 if total <= cap_bytes {
58 return;
59 }
60 entries.sort_by_key(|(_, _, mtime)| *mtime);
61 let mut count: usize = 0;
62 for (path, size, _) in entries {
63 if total <= cap_bytes {
64 break;
65 }
66 if std::fs::remove_file(&path).is_ok() {
67 total = total.saturating_sub(size);
68 }
69 count += 1;
70 if count.is_multiple_of(YIELD_EVERY) {
71 std::thread::yield_now();
72 }
73 }
74}
75
76fn collect_files(
77 dir: &std::path::Path,
78 out: &mut Vec<(PathBuf, u64, SystemTime)>,
79 total: &mut u64,
80) {
81 let Ok(read) = std::fs::read_dir(dir) else {
82 return;
83 };
84 for entry in read.flatten() {
85 let path = entry.path();
86 let Ok(metadata) = entry.metadata() else {
87 continue;
88 };
89 if metadata.is_dir() {
90 collect_files(&path, out, total);
91 continue;
92 }
93 let size = metadata.len();
94 let mtime = metadata.modified().unwrap_or(SystemTime::UNIX_EPOCH);
95 *total = total.saturating_add(size);
96 out.push((path, size, mtime));
97 }
98}