This commit is contained in:
bflatastic committed 2026-10-13 11:02:50 +07:00
commit a681a3c667
2 files changed
+36 -8

No files matched your search

+8 -8
View File
@@ -94,20 +94,20 @@ impl DiskCache {
if std::fs::create_dir_all(parent).is_err() {
return;
}
// know the current total before adding (the first scan must not count this file twice)
let _ = self.size();
// Serialize the file replacement and its size accounting. A repeated render of
// the same key replaces its JPEG; it must not count as another cache entry.
let mut total = self.total.lock().unwrap_or_else(|e| e.into_inner());
let used = total.get_or_insert_with(|| self.scan().iter().map(|f| f.1).sum());
let old_len = std::fs::metadata(&p).map_or(0, |m| m.len());
let tmp = p.with_extension(format!("tmp{:?}", std::thread::current().id()).replace(['(', ')'], ""));
if std::fs::write(&tmp, &bytes).is_err() || std::fs::rename(&tmp, &p).is_err() {
let _ = std::fs::remove_file(&tmp);
return;
}
self.writes.fetch_add(1, Ordering::Relaxed);
let over = {
let mut t = self.total.lock().unwrap_or_else(|e| e.into_inner());
let total = t.get_or_insert(0);
*total += bytes.len() as u64;
*total > self.budget()
};
*used = used.saturating_sub(old_len).saturating_add(bytes.len() as u64);
let over = *used > self.budget();
drop(total);
if over {
self.prune();
}
+28
View File
@@ -123,6 +123,34 @@ fn disk_cache_roundtrip_and_prune() {
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn disk_cache_overwrite_accounts_for_replaced_jpeg_only_once() {
let dir = temp_dir("overwrite");
let cache = DiskCache::new(&dir, 1 << 20);
let (a, b) = (hash_bytes(b"overwrite-a"), hash_bytes(b"overwrite-b"));
let first = gradient(80, 60, 4);
cache.put(a, &first);
cache.put(b, &gradient(80, 60, 7));
let initial = cache.size();
// Re-rendering the same key used to double-count bytes although the
// replacement occupied exactly the same pathname on disk.
cache.put(a, &first);
assert_eq!(cache.size(), initial);
assert!(cache.get(b).is_some());
// A replacement with a different encoded size must also update the total.
cache.put(a, &gradient(120, 90, 9));
let path = |key: Hash128| {
let hex = key.to_string();
dir.join(&hex[..2]).join(format!("{hex}.jpg"))
};
let actual = std::fs::metadata(path(a)).unwrap().len() + std::fs::metadata(path(b)).unwrap().len();
assert_eq!(cache.size(), actual);
cache.clear();
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn preview_cache_memory_then_disk() {
let dir = temp_dir("pc");