optimize file read in Config::verify

`Config::verify` refactored to improve the efficiency and
memory usage of file hashing.

Signed-off-by: onur-ozkan <work@onurozkan.dev>
This commit is contained in:
onur-ozkan 2023-10-14 22:52:05 +03:00
parent 7ed044c075
commit 3be453d0bb

View File

@ -320,25 +320,43 @@ impl Config {
} }
/// Returns whether the SHA256 checksum of `path` matches `expected`. /// Returns whether the SHA256 checksum of `path` matches `expected`.
fn verify(&self, path: &Path, expected: &str) -> bool { pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool {
use sha2::Digest; use sha2::Digest;
self.verbose(&format!("verifying {}", path.display())); self.verbose(&format!("verifying {}", path.display()));
if self.dry_run() {
return false;
}
let mut hasher = sha2::Sha256::new(); let mut hasher = sha2::Sha256::new();
// FIXME: this is ok for rustfmt (4.1 MB large at time of writing), but it seems memory-intensive for rustc and larger components.
// Consider using streaming IO instead? let file = t!(File::open(path));
let contents = if self.dry_run() { vec![] } else { t!(fs::read(path)) }; let mut reader = BufReader::new(file);
hasher.update(&contents);
let found = hex::encode(hasher.finalize().as_slice()); loop {
let verified = found == expected; let buffer = t!(reader.fill_buf());
if !verified && !self.dry_run() { let l = buffer.len();
// break if EOF
if l == 0 {
break;
}
hasher.update(buffer);
reader.consume(l);
}
let checksum = hex::encode(hasher.finalize().as_slice());
let verified = checksum == expected;
if !verified {
println!( println!(
"invalid checksum: \n\ "invalid checksum: \n\
found: {found}\n\ found: {checksum}\n\
expected: {expected}", expected: {expected}",
); );
} }
return verified;
verified
} }
} }