picca/src/main.rs

83 lines
2.2 KiB
Rust
Raw Normal View History

2025-07-15 21:06:35 -06:00
use sha2::{Sha256, Digest};
use std::ops::Deref;
use std::path::PathBuf;
use std::thread;
use std::thread::available_parallelism;
use std::fs::File;
use std::io;
use clap::Parser;
use std::sync::Arc;
use std::sync::Mutex;
use std::collections::VecDeque;
use std::fs;
#[derive(Parser)]
#[command(name = "psha")]
#[command(version = option_env!("CARGO_PKG_VERSION"))]
#[command(long_about = None)]
struct Args {
#[arg(
trailing_var_arg = true,
)]
files: Vec<PathBuf>,
}
fn checksum(thread_id: usize, filenames: Arc<Mutex<VecDeque<PathBuf>>>) -> Result<(), String> {
let running = true;
while running {
let filename = match filenames.lock().unwrap().pop_front() {
Some(f) => f,
None => return Ok(())
};
let mut hasher = Sha256::new();
let mut file = File::open(&filename).unwrap();
io::copy(&mut file, &mut hasher);
let hash = hasher.finalize();
// println!("thread {} result: {:x}\t{}", thread_id, hash, filename.as_path().display());
println!("{:x}\t{}", hash, filename.as_path().display());
}
println!("thread {} has ran out of work", thread_id);
Ok(())
}
fn main() {
let args = Args::parse();
let cpus = available_parallelism().unwrap().get();
let mut buffer = VecDeque::new();
let mut handles = vec![];
for file in args.files {
// match fs::canonicalize(file.as_path()) {
// Ok(p) => buffer.push_back(p),
// Err(e) => panic!("unable to canonicalize {}: {}", file.as_path().display(), e)
// };
buffer.push_back(file);
}
let arc_buf = Arc::new(Mutex::new(buffer));
// let mut handles = vec![];
// let chunks = Arc::new(Mutex::new(args.files.chunks(args.files.len()/ cpus).clone()));
/* let threads = chunks.into_iter().map(|chunk| {
thread::spawn(move || checksum(0, chunk.to_vec()))
}).collect::<Vec<_>>(); */
/* threads.into_iter().for_each(|i| { i.join().unwrap(); });
// for file in args.files {
// if let Err(e) = checksum(0, file) { */
// println!("{}", e);
// break;
// };
// }
for i in 0..cpus {
let safe = Arc::clone(&arc_buf);
handles.push(thread::spawn(move || checksum(i, safe)))
}
for handle in handles {
handle.join().unwrap();
}
// println!("{}", available_parallelism().unwrap().get());
}