Refactor and add comments
This commit is contained in:
parent
660391fb99
commit
3e55287a43
1 changed files with 40 additions and 24 deletions
64
src/main.rs
64
src/main.rs
|
@ -1,49 +1,63 @@
|
||||||
use digest::Digest;
|
use digest::{Digest, Output};
|
||||||
use md5::Md5;
|
use md5::Md5;
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
use std::{
|
use std::{
|
||||||
fs::File,
|
fs::File,
|
||||||
io::Read,
|
io::Read,
|
||||||
sync::{mpsc::sync_channel, Arc},
|
sync::{
|
||||||
|
mpsc::{sync_channel, Receiver},
|
||||||
|
Arc,
|
||||||
|
},
|
||||||
thread,
|
thread,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Spawns a hasher thread.
|
||||||
|
fn spwan_hasher<T>(rx: Receiver<Arc<Vec<u8>>>) -> thread::JoinHandle<Output<T>>
|
||||||
|
where
|
||||||
|
T: Digest,
|
||||||
|
{
|
||||||
|
thread::spawn(move || {
|
||||||
|
let mut hasher = T::new();
|
||||||
|
|
||||||
|
// Break when the sender is dropped.
|
||||||
|
while let Ok(buf) = rx.recv() {
|
||||||
|
hasher.update(&*buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
hasher.finalize()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// Open test file.
|
||||||
let mut file = File::open("test.txt").unwrap();
|
let mut file = File::open("test.txt").unwrap();
|
||||||
|
|
||||||
|
// Initialize channels.
|
||||||
|
let channel_bound = 1;
|
||||||
|
let (sha256_tx, sha256_rx) = sync_channel(channel_bound);
|
||||||
|
let (md5_tx, md5_rx) = sync_channel(channel_bound);
|
||||||
|
|
||||||
|
// Spawn hasher threads.
|
||||||
|
let sha256_handle = spwan_hasher::<Sha256>(sha256_rx);
|
||||||
|
let md5_handle = spwan_hasher::<Md5>(md5_rx);
|
||||||
|
|
||||||
|
// Initialize the reading buffer.
|
||||||
let mut buffer = vec![0; 4096];
|
let mut buffer = vec![0; 4096];
|
||||||
|
|
||||||
let mut sha256_hasher = Sha256::new();
|
|
||||||
let mut md5_hasher = Md5::new();
|
|
||||||
|
|
||||||
let channel_capacity = 1;
|
|
||||||
let (sha256_tx, sha256_rx) = sync_channel::<Arc<Vec<u8>>>(channel_capacity);
|
|
||||||
let (md5_tx, md5_rx) = sync_channel::<Arc<Vec<u8>>>(channel_capacity);
|
|
||||||
|
|
||||||
let sha256_handle = thread::spawn(move || {
|
|
||||||
while let Ok(buf) = sha256_rx.recv() {
|
|
||||||
sha256_hasher.update(&*buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
sha256_hasher.finalize()
|
|
||||||
});
|
|
||||||
let md5_handle = thread::spawn(move || {
|
|
||||||
while let Ok(buf) = md5_rx.recv() {
|
|
||||||
md5_hasher.update(&*buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
md5_hasher.finalize()
|
|
||||||
});
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
// Read into the buffer.
|
||||||
let n = file.read(&mut buffer).unwrap();
|
let n = file.read(&mut buffer).unwrap();
|
||||||
|
|
||||||
|
// Break if the file end is reached and there is nothing to read.
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clone the read bytes into a new buffer that is read by multiple threads.
|
||||||
|
// Arc prevents cloning for every thread.
|
||||||
let buffer_arc = Arc::new(buffer[..n].to_vec());
|
let buffer_arc = Arc::new(buffer[..n].to_vec());
|
||||||
|
|
||||||
|
// Send the buffer.
|
||||||
sha256_tx.send(Arc::clone(&buffer_arc)).unwrap();
|
sha256_tx.send(Arc::clone(&buffer_arc)).unwrap();
|
||||||
md5_tx.send(buffer_arc).unwrap();
|
md5_tx.send(buffer_arc).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -52,9 +66,11 @@ fn main() {
|
||||||
drop(sha256_tx);
|
drop(sha256_tx);
|
||||||
drop(md5_tx);
|
drop(md5_tx);
|
||||||
|
|
||||||
|
// Join threads.
|
||||||
let md5_result = md5_handle.join().unwrap();
|
let md5_result = md5_handle.join().unwrap();
|
||||||
let sha256_result = sha256_handle.join().unwrap();
|
let sha256_result = sha256_handle.join().unwrap();
|
||||||
|
|
||||||
|
// Print hashes.
|
||||||
println!("md5: {:?}", hex::encode(md5_result));
|
println!("md5: {:?}", hex::encode(md5_result));
|
||||||
println!("sha256: {:?}", hex::encode(sha256_result));
|
println!("sha256: {:?}", hex::encode(sha256_result));
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue