Last active
December 5, 2020 18:42
-
-
Save velikodniy/dd201b45d6020efe4647c6389a583c0f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use clap::{crate_name, crate_version, App, Arg}; | |
use indicatif::{ParallelProgressIterator, ProgressStyle}; | |
use murmur3::murmur3_x64_128; | |
use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; | |
use std::fs::metadata; | |
use std::fs::File; | |
use std::io::prelude::*; | |
use std::sync::{Arc, Mutex}; | |
use walkdir::WalkDir; | |
fn main() { | |
let matches = App::new(crate_name!()) | |
.version(crate_version!()) | |
.author("Vadim Velicodnii <vadim@velikodniy.name>") | |
.about("Computes MurMur3 (128 bit, x64) hashes for the files in a directory") | |
.arg( | |
Arg::with_name("dir_name") | |
.value_name("DIR") | |
.about("Directory for scanning") | |
.required(true), | |
) | |
.arg( | |
Arg::with_name("output_file") | |
.short('o') | |
.long("output") | |
.value_name("OUTPUT") | |
.about("File for the output") | |
.required(true), | |
) | |
.get_matches(); | |
let dir_name = matches.value_of("dir_name").unwrap(); | |
let files = WalkDir::new(dir_name) | |
.into_iter() | |
.filter_map(|e| e.ok()) | |
.collect::<Vec<_>>(); | |
let pbar = indicatif::ProgressBar::new(files.len() as u64); | |
pbar.set_style( | |
ProgressStyle::default_bar() | |
.template("[{elapsed_precise}] ETA: [{eta_precise}] {wide_bar} {pos:>7}/{len:7} {msg}"), | |
); | |
let output = File::create(matches.value_of("output_file").unwrap()).unwrap(); | |
let output_arc = Arc::new(Mutex::new(output)); | |
files | |
.par_iter() | |
.progress_with(pbar) | |
.filter_map(|e| { | |
if metadata(e.path()).unwrap().is_file() { | |
Some(e) | |
} else { | |
None | |
} | |
}) | |
.map(|e| { | |
let mut file = File::open(e.path()).unwrap(); | |
let hash = murmur3_x64_128(&mut file, 0).unwrap(); | |
(e, hash) | |
}) | |
.for_each(|d| { | |
let (e, h) = d; | |
let line = format!("{:032x} {}\n", h, e.path().display()); | |
if output_arc.lock().unwrap().write_all(line.as_bytes()).is_err() { | |
panic!("unable to write to the file") | |
}; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment