C14.11 r1: fingerprints carry the file's identity; stale disk reads never land
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
1dc0d31615
commit
e2cb83ceaa
6 files changed
+86
-3
No files matched your search
@@ -4,11 +4,13 @@ use std::{
|
||||
time::SystemTime,
|
||||
};
|
||||
|
||||
/// Length and mtime when last loaded or saved.
|
||||
/// Length, mtime and identity when last loaded or saved.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Fingerprint {
|
||||
pub len: u64,
|
||||
pub modified: SystemTime,
|
||||
/// A replace with the same time is a new file.
|
||||
pub id: Option<(u64, u64)>,
|
||||
}
|
||||
|
||||
impl Fingerprint {
|
||||
@@ -17,6 +19,7 @@ impl Fingerprint {
|
||||
Ok(Self {
|
||||
len: meta.len(),
|
||||
modified: meta.modified()?,
|
||||
id: file_id(path)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,3 +482,19 @@ fn a_stale_load_callback_keeps_the_reloaded_state() {
|
||||
}
|
||||
|
||||
mod failed;
|
||||
|
||||
#[test]
|
||||
fn a_replace_with_the_same_time_and_size_is_a_new_fingerprint() {
|
||||
let dir = tempfile::tempdir().expect("a temp dir");
|
||||
let (path, next) = (dir.path().join("a.md"), dir.path().join("a.md.new"));
|
||||
write(&path, "old text\n");
|
||||
let before = Fingerprint::of(&path).expect("the first fingerprint");
|
||||
write(&next, "new text\n");
|
||||
let file = std::fs::File::options().write(true).open(&next).expect("the new file");
|
||||
file.set_modified(before.modified).expect("the old time");
|
||||
drop(file);
|
||||
std::fs::rename(&next, &path).expect("the replace");
|
||||
let after = Fingerprint::of(&path).expect("the second fingerprint");
|
||||
assert_eq!((after.len, after.modified), (before.len, before.modified));
|
||||
assert_ne!(after, before, "the identity tells them apart");
|
||||
}
|
||||
Reference in new issue
Block a user