Main: Add spinner printing out hashing throughput
This commit is contained in:
parent
9056adb574
commit
24398c0994
1 changed files with 40 additions and 29 deletions
69
src/main.rs
69
src/main.rs
|
@ -6,9 +6,11 @@
|
||||||
|
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use indicatif::{ParallelProgressIterator, ProgressBar, ProgressStyle, ProgressFinish};
|
use indicatif::{MultiProgress, ParallelProgressIterator, ProgressBar, ProgressFinish, ProgressStyle};
|
||||||
use rayon::ThreadPoolBuilder;
|
use rayon::ThreadPoolBuilder;
|
||||||
use rayon::iter::{ParallelIterator, IntoParallelRefIterator};
|
use rayon::iter::{ParallelIterator, IntoParallelRefIterator};
|
||||||
|
use core::option::Option::None;
|
||||||
|
use core::time::Duration;
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
@ -65,10 +67,19 @@ fn run() -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let progress_bar = ProgressBar::new(hashed_files.len() as u64);
|
let multi_progress = MultiProgress::new();
|
||||||
progress_bar.set_style(ProgressStyle::default_bar()
|
|
||||||
.template("Hashing files... {bar} {pos:>7}/{len:7} [{elapsed_precise}] ")
|
let progress_bar = ProgressBar::new(hashed_files.len() as u64)
|
||||||
.on_finish(ProgressFinish::AndLeave));
|
.with_finish(ProgressFinish::AndLeave)
|
||||||
|
.with_style(ProgressStyle::default_bar()
|
||||||
|
.template("Hashing files... {bar} {pos:>7}/{len:7} [{elapsed_precise}]").unwrap());
|
||||||
|
|
||||||
|
let throughput_spinner = ProgressBar::new_spinner()
|
||||||
|
.with_style(ProgressStyle::default_spinner()
|
||||||
|
.template("{bytes_per_sec}").unwrap());
|
||||||
|
|
||||||
|
multi_progress.add(progress_bar.clone());
|
||||||
|
multi_progress.add(throughput_spinner.clone());
|
||||||
|
|
||||||
let pool = ThreadPoolBuilder::new().num_threads(args.jobs as usize).build().unwrap();
|
let pool = ThreadPoolBuilder::new().num_threads(args.jobs as usize).build().unwrap();
|
||||||
|
|
||||||
|
@ -87,40 +98,40 @@ fn run() -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pool.install(|| {
|
throughput_spinner.enable_steady_tick(Duration::from_millis(100));
|
||||||
return hashed_files.par_iter().progress_with(progress_bar).try_for_each(|path| -> Result<()> {
|
|
||||||
// Just opening the file and hashing using io::copy is roughly ~2.5x faster compared to sha256::digest_file
|
|
||||||
let mut hasher = Sha256::new();
|
|
||||||
let mut file = File::open(path)?;
|
|
||||||
|
|
||||||
io::copy(&mut file, &mut hasher)?;
|
pool.install(|| hashed_files.par_iter().progress_with(progress_bar).try_for_each(|path| -> Result<()> {
|
||||||
|
// Just opening the file and hashing using io::copy is roughly ~2.5x faster compared to sha256::digest_file
|
||||||
|
let mut hasher = Sha256::new();
|
||||||
|
let mut file = File::open(path)?;
|
||||||
|
|
||||||
let hash = format!("{:x}", hasher.finalize());
|
io::copy(&mut file, &mut throughput_spinner.wrap_write(&mut hasher))?;
|
||||||
let filename = path.file_name().unwrap().to_str().unwrap();
|
|
||||||
|
|
||||||
if filename != hash {
|
let hash = format!("{:x}", hasher.finalize());
|
||||||
let path_string = path.to_str().unwrap();
|
let filename = path.file_name().unwrap().to_str().unwrap();
|
||||||
|
|
||||||
eprintln!("Integrity check failed for {}: Expected {}, got {}", path_string, filename, hash);
|
if filename != hash {
|
||||||
|
let path_string = path.to_str().unwrap();
|
||||||
|
|
||||||
let file = OpenOptions::new()
|
eprintln!("Integrity check failed for {}: Expected {}, got {}", path_string, filename, hash);
|
||||||
.create(true)
|
|
||||||
.append(true)
|
|
||||||
.open("restic-integrity-log");
|
|
||||||
|
|
||||||
match file {
|
let file = OpenOptions::new()
|
||||||
Err(error) => eprintln!("Unable to write to restic-integrity-log: {}", error),
|
.create(true)
|
||||||
Ok(mut file) => {
|
.append(true)
|
||||||
if let Err(error) = writeln!(file, "{}: Integrity check failed for {}: Expected {}, got {}", Local::now().format("%Y-%m-%d %H:%M:%S"), path_string, filename, hash) {
|
.open("restic-integrity-log");
|
||||||
eprintln!("Unable to write to restic-integrity-log: {}", error)
|
|
||||||
}
|
match file {
|
||||||
|
Err(error) => eprintln!("Unable to write to restic-integrity-log: {}", error),
|
||||||
|
Ok(mut file) => {
|
||||||
|
if let Err(error) = writeln!(file, "{}: Integrity check failed for {}: Expected {}, got {}", Local::now().format("%Y-%m-%d %H:%M:%S"), path_string, filename, hash) {
|
||||||
|
eprintln!("Unable to write to restic-integrity-log: {}", error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
}))
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
Loading…
Reference in a new issue