mirror of
https://github.com/rust-lang-nursery/rust-cookbook
synced 2024-11-21 19:13:07 +00:00
Use a threadpool to calculate SHA1 in all iso files in a folder.
This commit is contained in:
parent
cb762da0eb
commit
859953cf3a
2 changed files with 88 additions and 0 deletions
|
@ -7,6 +7,7 @@
|
|||
| [Generate jpg thumbnails in parallel][ex-rayon-thumbnails] | [![rayon-badge]][rayon] [![glob-badge]][glob] [![image-badge]][image] | [![cat-concurrency-badge]][cat-concurrency][![cat-filesystem-badge]][cat-filesystem] |
|
||||
| [Spawn a short-lived thread][ex-crossbeam-spawn] | [![crossbeam-badge]][crossbeam] | [![cat-concurrency-badge]][cat-concurrency] |
|
||||
| [Draw fractal dispatching work to a thread pool][ex-threadpool-fractal] | [![threadpool-badge]][threadpool] [![num-badge]][num] [![num_cpus-badge]][num_cpus] [![image-badge]][image] | [![cat-concurrency-badge]][cat-concurrency][![cat-science-badge]][cat-science][![cat-rendering-badge]][cat-rendering] |
|
||||
| [Calculate SHA1 sum of *.iso files concurrently][threadpool-walk] | [![threadpool-badge]][threadpool] [![walkdir-badge]][walkdir] [![num_cpus-badge]][num_cpus] [![ring-badge]][ring] | [![cat-concurrency-badge]][cat-concurrency][![cat-filesystem-badge]][cat-filesystem] |
|
||||
|
||||
[ex-rayon-iter-mut]: #ex-rayon-iter-mut
|
||||
<a name="ex-rayon-iter-mut"></a>
|
||||
|
@ -315,6 +316,91 @@ fn run() -> Result<()> {
|
|||
# quick_main!(run);
|
||||
```
|
||||
|
||||
[threadpool-walk]: #threadpool-walk
|
||||
<a name="threadpool-walk"></a>
|
||||
|
||||
## Calculate SHA1 sum of *.iso files concurrently
|
||||
|
||||
[![threadpool-badge]][threadpool] [![num_cpus-badge]][num_cpus] [![walkdir-badge]][walkdir] [![ring-badge]][ring] [![cat-concurrency-badge]][cat-concurrency][![cat-filesystem-badge]][cat-filesystem]
|
||||
|
||||
This example calculates the SHA1 for every file present in the current directory. A threadpool is created using the number of cpus present in the system with [`num_cpus::get`]. Then every returned by [`Walkdir::new`] is passed into this pool to perform the operations of reading and computing SHA1. At the end the program waits for all jobs to finish. To get better results, compile this program in release mode.
|
||||
|
||||
```rust,no_run
|
||||
# #[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;
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Read};
|
||||
use std::path::Path;
|
||||
use threadpool::ThreadPool;
|
||||
use std::sync::mpsc::channel;
|
||||
use ring::digest::{Context, Digest, SHA1};
|
||||
|
||||
# // Verify the iso extension
|
||||
# fn is_iso(entry: &Path) -> bool {
|
||||
# match entry.extension() {
|
||||
# Some(e) if e.to_string_lossy().to_lowercase() == "iso" => true,
|
||||
# _ => false,
|
||||
# }
|
||||
# }
|
||||
#
|
||||
fn compute_digest<P: AsRef<Path>>(filepath: P) -> Result<(Digest, P)> {
|
||||
let mut buf_reader = BufReader::new(File::open(&filepath)?);
|
||||
let mut context = Context::new(&SHA1);
|
||||
let mut buffer = [0; 1024];
|
||||
|
||||
loop {
|
||||
let count = buf_reader.read(&mut buffer)?;
|
||||
if count == 0 {
|
||||
break;
|
||||
}
|
||||
context.update(&buffer[..count]);
|
||||
}
|
||||
|
||||
Ok((context.finish(), filepath))
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let pool = ThreadPool::new(num_cpus::get());
|
||||
|
||||
let (tx, rx) = channel();
|
||||
|
||||
// Look in the current directory.
|
||||
for entry in WalkDir::new("/home/user/Downloads")
|
||||
.follow_links(true)
|
||||
.into_iter()
|
||||
.filter_map(|e| e.ok())
|
||||
.filter(|e| !e.path().is_dir() && is_iso(e.path())) {
|
||||
let path = entry.path().to_owned();
|
||||
let tx = tx.clone();
|
||||
pool.execute(move || {
|
||||
let digest = compute_digest(path);
|
||||
tx.send(digest).expect("Could not send data!");
|
||||
});
|
||||
}
|
||||
|
||||
drop(tx);
|
||||
for t in rx.iter() {
|
||||
let (sha, path) = t?;
|
||||
println!("{:?} {:?}", sha, path);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
#
|
||||
# quick_main!(run);
|
||||
```
|
||||
|
||||
{{#include links.md}}
|
||||
|
||||
<!-- API Reference -->
|
||||
|
@ -337,6 +423,7 @@ fn run() -> Result<()> {
|
|||
[`par_iter`]: https://docs.rs/rayon/*/rayon/iter/trait.IntoParallelRefIterator.html#tymethod.par_iter
|
||||
[`par_iter_mut`]: https://docs.rs/rayon/*/rayon/iter/trait.IntoParallelRefMutIterator.html#tymethod.par_iter_mut
|
||||
[`par_sort_unstable`]: https://docs.rs/rayon/*/rayon/slice/trait.ParallelSliceMut.html#method.par_sort_unstable
|
||||
[`Walkdir::new`]: https://docs.rs/walkdir/1.0.7/walkdir/struct.WalkDir.html#method.new
|
||||
|
||||
<!-- Other Reference -->
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ community. It needs and welcomes help. For details see
|
|||
| [Generate jpg thumbnails in parallel][ex-rayon-thumbnails] | [![rayon-badge]][rayon] [![glob-badge]][glob] [![image-badge]][image] | [![cat-concurrency-badge]][cat-concurrency][![cat-filesystem-badge]][cat-filesystem] |
|
||||
| [Spawn a short-lived thread][ex-crossbeam-spawn] | [![crossbeam-badge]][crossbeam] | [![cat-concurrency-badge]][cat-concurrency] |
|
||||
| [Draw fractal dispatching work to a thread pool][ex-threadpool-fractal] | [![threadpool-badge]][threadpool] [![num-badge]][num] [![num_cpus-badge]][num_cpus] [![image-badge]][image] | [![cat-concurrency-badge]][cat-concurrency][![cat-science-badge]][cat-science][![cat-rendering-badge]][cat-rendering] |
|
||||
| [Calculate SHA1 sum of *.iso files concurrently][threadpool-walk] | [![threadpool-badge]][threadpool] [![walkdir-badge]][walkdir] [![num_cpus-badge]][num_cpus] [![ring-badge]][ring] | [![cat-concurrency-badge]][cat-concurrency][![cat-filesystem-badge]][cat-filesystem] |
|
||||
|
||||
## [Networking](net.html)
|
||||
|
||||
|
|
Loading…
Reference in a new issue