From 351cceab7d1d60944a4c35bc2cc15ebccd337428 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Tue, 7 Aug 2018 11:04:19 +0200 Subject: [PATCH] implement working solution --- src/main.rs | 67 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/src/main.rs b/src/main.rs index c70b2c2..42d3db4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -240,37 +240,50 @@ fn main() { } // compute file hash in parallel - let magic = files_candidate.lock().unwrap().len() / num_cpus::get(); - println!("Magic is : {}", magic); + let num_cpus = num_cpus::get(); + let files_candidate_len = files_candidate.lock().unwrap().len(); + let chunk_size = (files_candidate_len / num_cpus) + 1; + let modulus = files_candidate_len % num_cpus; - 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| { + println!("Calculate {} file(s)", files_candidate_len); + println!("Use {} chunk(s) of size {}", modulus, chunk_size); + println!("Use {} chunk(s) of size {}", num_cpus - modulus, chunk_size - 1); + + let mut guards = vec![]; + let fc = files_candidate.clone(); + let mut work = fc.lock().unwrap(); + + // Example from : + // https://stackoverflow.com%2Fquestions/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| { + let (split_a, split_b) = work.split_at_mut(chunk_size * modulus); + let chunk_a = split_a.chunks_mut(chunk_size); + let chunk_b = split_b.chunks_mut(chunk_size - 1); + + for (i, slice) in chunk_a.chain(chunk_b).enumerate() { // 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); - } - } - ); - }); + let guard = scope.spawn(move || { + for w in slice { + println!("[{}] Hashing : {}", i, w); + //thread::sleep(std::time::Duration::from_secs(2)); + if let Ok(mut file) = fs::File::open(&w.name) { + w.hash::(&mut file); + } else { + panic!("Error opening file (name = {})!", w.name); + } + } + }); + guards.push(guard); + } + }); + + for guard in guards { + guard.join(); } - for i in files_candidate.lock().unwrap().iter() { + for i in work.iter() { println!("{}", i); }