From 8826a87f3277ca719c133321f70e6fb09377e8d4 Mon Sep 17 00:00:00 2001 From: sreedevk Date: Sat, 12 Jul 2025 21:17:00 +0000 Subject: [PATCH] added strict mode with partial hashing default --- src/params.rs | 3 +++ src/processor.rs | 60 ++++++++++++++++++++++++++---------------------- src/server.rs | 10 ++++---- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/params.rs b/src/params.rs index 2e302e3..5a8ec7c 100644 --- a/src/params.rs +++ b/src/params.rs @@ -30,6 +30,9 @@ pub struct Params { /// print json output #[arg(long)] pub json: bool, + /// Guarantees that two files are duplicate (performs a full hash) + #[arg(long, short = 'f', default_value = "false")] + pub strict: bool, } impl Params { diff --git a/src/processor.rs b/src/processor.rs index b2346de..deece81 100644 --- a/src/processor.rs +++ b/src/processor.rs @@ -8,11 +8,13 @@ use std::sync::{Arc, Mutex, TryLockError, TryLockResult}; use std::time::Duration; use crate::fileinfo::FileInfo; +use crate::params::Params; pub struct Processor {} impl Processor { pub fn hashwise( + app_args: Arc, sw_store: Arc>>, hw_store: Arc>>, ) -> Result<()> { @@ -32,8 +34,14 @@ impl Processor { let group: Vec = sw_store.get(&key).unwrap().to_vec(); if group.len() > 1 { group.into_par_iter().for_each(|file| { + let fhash = if app_args.strict { + file.hash().expect("hashing file failed.") + } else { + file.initial_page_hash().expect("hashing file failed.") + }; + hw_store - .entry(file.hash().expect("hashing file failed.")) + .entry(fhash) .and_modify(|fileset| fileset.push(file.clone())) .or_insert_with(|| vec![file]); }); @@ -51,7 +59,6 @@ impl Processor { Ok(()) } - // TODO: reduce the amount of time files remain locked for pub fn sizewise( scanner_finished: Arc, store: Arc>>, @@ -65,32 +72,31 @@ impl Processor { progress_bar.set_message("files grouped by size"); loop { - match files.try_lock() { - Ok(mut flist) => match flist.pop() { - Some(file) => { - progress_bar.inc(1); - Self::compare_and_update_max_path_len( - max_file_size.clone(), - file.path.to_string_lossy().len() as u64, - )?; - store - .entry(file.size) - .and_modify(|fileset| fileset.push(file.clone())) - .or_insert_with(|| vec![file]); - continue; - } - None => match scanner_finished.load(std::sync::atomic::Ordering::Relaxed) { - true => break Ok(()), - false => continue, - }, - }, - TryLockResult::Err(TryLockError::WouldBlock) => continue, - _ => { - break { - progress_bar.finish_with_message("files grouped by size."); - Ok(()) - } + let fileopt: Option = { + match files.try_lock() { + Ok(mut flist) => flist.pop(), + TryLockResult::Err(TryLockError::WouldBlock) => None, + _ => None, } + }; + + match fileopt { + Some(file) => { + progress_bar.inc(1); + Self::compare_and_update_max_path_len( + max_file_size.clone(), + file.path.to_string_lossy().len() as u64, + )?; + store + .entry(file.size) + .and_modify(|fileset| fileset.push(file.clone())) + .or_insert_with(|| vec![file]); + continue; + } + None => match scanner_finished.load(std::sync::atomic::Ordering::Relaxed) { + true => break Ok(()), + false => continue, + }, } } } diff --git a/src/server.rs b/src/server.rs index 0c2ed96..a04afd4 100644 --- a/src/server.rs +++ b/src/server.rs @@ -25,14 +25,15 @@ impl Server { filequeue: Arc::new(Mutex::new(Vec::new())), sw_duplicate_set: Arc::new(DashMap::new()), hw_duplicate_set: Arc::new(DashMap::new()), - threadpool: ThreadPool::new(8), + threadpool: ThreadPool::new(4), app_args: Arc::new(opts), max_file_path_len: Arc::new(AtomicU64::new(0)), } } pub fn start(&self) -> Result<()> { - let app_args_clone = self.app_args.clone(); + let app_args_clone_for_sc = self.app_args.clone(); + let app_args_clone_for_pr = self.app_args.clone(); let file_queue_clone_sc = self.filequeue.clone(); let file_queue_clone_pr = self.filequeue.clone(); let scanner_finished = Arc::new(AtomicBool::new(false)); @@ -46,7 +47,7 @@ impl Server { let max_file_path_len_clone = self.max_file_path_len.clone(); self.threadpool.execute(move || { - Scanner::build(app_args_clone) + Scanner::build(app_args_clone_for_sc) .unwrap() .scan(file_queue_clone_sc) .unwrap(); @@ -63,7 +64,8 @@ impl Server { ) .unwrap(); - Processor::hashwise(store_dupl_sw_for_hw, store_dupl_hw).unwrap(); + Processor::hashwise(app_args_clone_for_pr, store_dupl_sw_for_hw, store_dupl_hw) + .unwrap(); }); self.threadpool.join();