From 3e55287a43bb12d631c0f96c475b30bc25c78d92 Mon Sep 17 00:00:00 2001 From: mo8it Date: Wed, 19 Apr 2023 22:56:28 +0200 Subject: [PATCH] Refactor and add comments --- src/main.rs | 64 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/src/main.rs b/src/main.rs index fc822af..f900515 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,49 +1,63 @@ -use digest::Digest; +use digest::{Digest, Output}; use md5::Md5; use sha2::Sha256; use std::{ fs::File, io::Read, - sync::{mpsc::sync_channel, Arc}, + sync::{ + mpsc::{sync_channel, Receiver}, + Arc, + }, thread, }; +// Spawns a hasher thread. +fn spwan_hasher(rx: Receiver>>) -> thread::JoinHandle> +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() { + // Open test file. 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_rx); + let md5_handle = spwan_hasher::(md5_rx); + + // Initialize the reading buffer. 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::>>(channel_capacity); - let (md5_tx, md5_rx) = sync_channel::>>(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 { + // Read into the buffer. let n = file.read(&mut buffer).unwrap(); + // Break if the file end is reached and there is nothing to read. if n == 0 { 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()); + // Send the buffer. sha256_tx.send(Arc::clone(&buffer_arc)).unwrap(); md5_tx.send(buffer_arc).unwrap(); } @@ -52,9 +66,11 @@ fn main() { drop(sha256_tx); drop(md5_tx); + // Join threads. let md5_result = md5_handle.join().unwrap(); let sha256_result = sha256_handle.join().unwrap(); + // Print hashes. println!("md5: {:?}", hex::encode(md5_result)); println!("sha256: {:?}", hex::encode(sha256_result)); }