diff --git a/Cargo.toml b/Cargo.toml index 5fab93e..a98ac03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,5 @@ term = "*" sha2 = "0.7.1" walkdir = "*" time = "*" +num_cpus = "*" +crossbeam = "*" diff --git a/src/main.rs b/src/main.rs index 6d6385d..c70b2c2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,8 @@ extern crate term; extern crate sha2; extern crate walkdir; extern crate time; +extern crate num_cpus; +extern crate crossbeam; use time::PreciseTime; @@ -206,7 +208,8 @@ fn main() { } let start = PreciseTime::now(); - // Walk through path 1 & 2 [Todo: threading] + + // Walk through path 1 & 2 with 2 threads let mut children = vec![]; let args_source = vec![args.input, args.output]; for s in args_source { @@ -221,39 +224,59 @@ fn main() { let ft = metadata.file_type(); if ft.is_file() { - if let Ok(mut file) = fs::File::open(&entry.path()) { let mut a = FileToProcess { name: format!("{}", entry.path().display()), hash: vec![], realpath: String::from("TODO"), }; - - // compute file hash - a.hash::(&mut file); fc.lock().unwrap().push(a); - } } } })); } - for child in children { - // Wait for the thread to finish. Returns a result. let _ = child.join(); } + // compute file hash in parallel + let magic = files_candidate.lock().unwrap().len() / num_cpus::get(); + println!("Magic is : {}", magic); + + for i in 0..num_cpus::get()+1 { + let fc = files_candidate.clone(); + let mut work = fc.lock().unwrap(); + let end = if (i*magic)+(magic) > work.len() { + work.len() + } else { + (i*magic)+(magic) + }; + // Example from : + // https://stackoverflow.com/questions/33818141/how-do-i-pass-disjoint-slices-from-a-vector-to-different-threads + // Scoped threads allow the compiler to prove that no threads will outlive + // table (which would be bad). + crossbeam::scope(|scope| { + // Spawn a thread operating on that subslice. + scope.spawn(move || + for w in &mut work[i*magic .. end] { + println!("[{}] Hashing : {}", i, w); + if let Ok(mut file) = fs::File::open(&w.name) { + w.hash::(&mut file); + } else { + panic!("Error opening file (name = {})!", w.name); + } + } + ); + }); + } + for i in files_candidate.lock().unwrap().iter() { println!("{}", i); } - // Condition: Filename (basename) Must be the same (?) - - // whatever you want to do + t.fg(term::color::CYAN).unwrap(); let end = PreciseTime::now(); println!("{} seconds.", start.to(end)); t.reset().unwrap(); - t.fg(term::color::CYAN).unwrap(); - println!("Cheers !"); }