Use crossbeam and num_cpu

master
Benoît 2018-07-09 14:48:20 +02:00
parent 1b5157b80a
commit 1cdc35562b
2 changed files with 38 additions and 13 deletions

View File

@ -9,3 +9,5 @@ term = "*"
sha2 = "0.7.1" sha2 = "0.7.1"
walkdir = "*" walkdir = "*"
time = "*" time = "*"
num_cpus = "*"
crossbeam = "*"

View File

@ -3,6 +3,8 @@ extern crate term;
extern crate sha2; extern crate sha2;
extern crate walkdir; extern crate walkdir;
extern crate time; extern crate time;
extern crate num_cpus;
extern crate crossbeam;
use time::PreciseTime; use time::PreciseTime;
@ -206,7 +208,8 @@ fn main() {
} }
let start = PreciseTime::now(); let start = PreciseTime::now();
// Walk through path 1 & 2 [Todo: threading]
// Walk through path 1 & 2 with 2 threads
let mut children = vec![]; let mut children = vec![];
let args_source = vec![args.input, args.output]; let args_source = vec![args.input, args.output];
for s in args_source { for s in args_source {
@ -221,39 +224,59 @@ fn main() {
let ft = metadata.file_type(); let ft = metadata.file_type();
if ft.is_file() { if ft.is_file() {
if let Ok(mut file) = fs::File::open(&entry.path()) {
let mut a = FileToProcess { let mut a = FileToProcess {
name: format!("{}", name: format!("{}",
entry.path().display()), entry.path().display()),
hash: vec![], hash: vec![],
realpath: String::from("TODO"), realpath: String::from("TODO"),
}; };
// compute file hash
a.hash::<Sha256, _>(&mut file);
fc.lock().unwrap().push(a); fc.lock().unwrap().push(a);
}
} }
} }
})); }));
} }
for child in children { for child in children {
// Wait for the thread to finish. Returns a result.
let _ = child.join(); 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::<Sha256, _>(&mut file);
} else {
panic!("Error opening file (name = {})!", w.name);
}
}
);
});
}
for i in files_candidate.lock().unwrap().iter() { for i in files_candidate.lock().unwrap().iter() {
println!("{}", i); println!("{}", i);
} }
// Condition: Filename (basename) Must be the same (?) t.fg(term::color::CYAN).unwrap();
// whatever you want to do
let end = PreciseTime::now(); let end = PreciseTime::now();
println!("{} seconds.", start.to(end)); println!("{} seconds.", start.to(end));
t.reset().unwrap(); t.reset().unwrap();
t.fg(term::color::CYAN).unwrap();
println!("Cheers !");
} }