Skip to content

Instantly share code, notes, and snippets.

@ericho
Created September 4, 2017 13:39
Show Gist options
  • Save ericho/4a6b2d9feeb4b5abb2d4bfb7b5a76e78 to your computer and use it in GitHub Desktop.
Save ericho/4a6b2d9feeb4b5abb2d4bfb7b5a76e78 to your computer and use it in GitHub Desktop.
Example of threapool usage
#[macro_use]
extern crate error_chain;
extern crate walkdir;
extern crate ring;
extern crate num_cpus;
extern crate threadpool;
// error_chain! {
// foreign_links {
// Io(std::io::Error);
// }
// }
use walkdir::{WalkDir, DirEntry};
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use threadpool::ThreadPool;
use std::sync::mpsc::channel;
use ring::digest;
// Verify the iso extension
fn is_iso(entry: &DirEntry) -> bool {
entry.file_name()
.to_str()
.map(|s| s.ends_with(".iso"))
.unwrap_or(false)
}
fn run() -> Result<()> {
let cpus = num_cpus::get();
let pool = ThreadPool::new(cpus);
let mut file_counter: usize = 0;
let (tx, rx) = channel();
for entry in WalkDir::new(".")
.follow_links(true)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| !e.file_type().is_dir() && is_iso(e)) {
// Need to know how many entry were sent to the pool.
file_counter = file_counter + 1;
let entry = entry.clone();
let tx = tx.clone();
pool.execute(move || {
let file = match File::open(entry.path()) {
Ok(file) => file,
Err(err) => {
tx.send(Err(err)).expect("Could not send data!");
return;
},
};
let mut buf_reader = BufReader::new(file);
let mut content: Vec<u8> = Vec::new();
buf_reader.read_to_end(&mut content);
// Compute the SHA1
let digest = digest::digest(&digest::SHA1, &content);
let file_path = String::from(entry.path().to_string_lossy());
// Send as a Result
tx.send(Ok((digest, file_path))).expect("Could not send data!");
});
}
for t in rx.iter().take(file_counter) {
let (sha, path) = t?;
println!("{:?} {}", sha, path);
}
Ok(())
}
quick_main!(run);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment