fix: single file hash groups printed to screen

This commit is contained in:
sreedevk
2025-07-19 14:17:59 +00:00
parent 360af25318
commit f5d2d4e22c
6 changed files with 49 additions and 21 deletions

2
.cargo/config.toml Normal file
View File

@@ -0,0 +1,2 @@
[build]
rustflags = ["-C", "target-feature=+aes,+sse2"]

2
Cargo.lock generated
View File

@@ -273,7 +273,7 @@ dependencies = [
[[package]] [[package]]
name = "deduplicator" name = "deduplicator"
version = "0.3.1" version = "0.3.2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytesize", "bytesize",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "deduplicator" name = "deduplicator"
version = "0.3.1" version = "0.3.2"
edition = "2021" edition = "2021"
description = "find,filter and delete duplicate files" description = "find,filter and delete duplicate files"
repository = "https://github.com/sreedevk/deduplicator" repository = "https://github.com/sreedevk/deduplicator"

View File

@@ -155,6 +155,8 @@ dust 'bench_artifacts'
## proposed ## proposed
- [ ] parallelization - [ ] parallelization
- [ ] scanning + processing sw + processing hw + formatting + printing - [ ] scanning + processing sw + processing hw + formatting + printing
- [ ] user supplied cache file path for faster re-runs
- [ ] hardlinks / symlinks support
- [ ] max file path size should use the last set of duplicates - [ ] max file path size should use the last set of duplicates
- [ ] add more unit tests - [ ] add more unit tests
- [ ] test against different filesystems - [ ] test against different filesystems
@@ -177,6 +179,9 @@ dust 'bench_artifacts'
- [ ] append the offset between the last initial page hashed and the first final page hashed in the content passed to the hasher. - [ ] append the offset between the last initial page hashed and the first final page hashed in the content passed to the hasher.
- [ ] fix: --exclude-types and --types flag behave identically. - [ ] fix: --exclude-types and --types flag behave identically.
## v0.3.2
- [x] fix: single file groups are printed to screen
## v0.3.1 ## v0.3.1
- [x] parallelization - [x] parallelization
- [x] (scanning + processing sw + processing hw) & formatting & printing - [x] (scanning + processing sw + processing hw) & formatting & printing

View File

@@ -4,6 +4,7 @@ use chrono::{DateTime, Utc};
use dashmap::DashMap; use dashmap::DashMap;
use pathdiff::diff_paths; use pathdiff::diff_paths;
use rayon::prelude::*; use rayon::prelude::*;
use std::sync::atomic::AtomicU64;
use std::{path::PathBuf, sync::Arc}; use std::{path::PathBuf, sync::Arc};
const YELLOW: &str = "\x1b[33m"; const YELLOW: &str = "\x1b[33m";
@@ -39,26 +40,34 @@ impl Formatter {
if raw.is_empty() { if raw.is_empty() {
println!("No duplicates found matching your search criteria."); println!("No duplicates found matching your search criteria.");
} else { } else {
let printed_count: AtomicU64 = AtomicU64::new(0);
raw.par_iter().for_each(|sref| { raw.par_iter().for_each(|sref| {
let mut ostring = format!("{}{:32x}{}\n", YELLOW, sref.key(), RESET); if sref.value().len() > 1 {
let subfields = sref printed_count.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
.value() let mut ostring = format!("{}{:32x}{}\n", YELLOW, sref.key(), RESET);
.par_iter() let subfields = sref
.map(|finfo| { .value()
format!( .par_iter()
"├─ {}\t{}\t{}\n", .map(|finfo| {
Self::human_path(finfo, aargs, max_path_len as usize) format!(
.expect("path formatting failed."), "├─ {}\t{}\t{}\n",
Self::human_filesize(finfo).expect("filesize formatting failed."), Self::human_path(finfo, aargs, max_path_len as usize)
Self::human_mtime(finfo).expect("modified time formatting failed.") .expect("path formatting failed."),
) Self::human_filesize(finfo).expect("filesize formatting failed."),
}) Self::human_mtime(finfo).expect("modified time formatting failed.")
.collect::<String>(); )
})
.collect::<String>();
ostring.push_str(&subfields); ostring.push_str(&subfields);
println!("{ostring}");
println!("{ostring}"); }
}); });
if printed_count.load(std::sync::atomic::Ordering::Relaxed) < 1 {
println!("No duplicates found matching your search criteria.");
}
} }
} }
} }

View File

@@ -2,6 +2,7 @@ use crate::{fileinfo::FileInfo, formatter::Formatter, params::Params};
use anyhow::Result; use anyhow::Result;
use dashmap::DashMap; use dashmap::DashMap;
use prettytable::{format, row, Table}; use prettytable::{format, row, Table};
use std::sync::atomic::AtomicU64;
use std::{ use std::{
io::{self, Write}, io::{self, Write},
sync::Arc, sync::Arc,
@@ -11,12 +12,19 @@ pub struct Interactive;
impl Interactive { impl Interactive {
pub fn init(result: Arc<DashMap<u128, Vec<FileInfo>>>, app_args: &Params) -> Result<()> { pub fn init(result: Arc<DashMap<u128, Vec<FileInfo>>>, app_args: &Params) -> Result<()> {
result let store = result.clone();
.clone() if store.is_empty() {
println!("No duplicates found matching your search criteria.");
}
let printed_count: AtomicU64 = AtomicU64::new(0);
store
.iter() .iter()
.filter(|i| i.value().len() > 1) .filter(|i| i.value().len() > 1)
.enumerate() .enumerate()
.for_each(|(gindex, i)| { .for_each(|(gindex, i)| {
printed_count.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
let group = i.value(); let group = i.value();
let mut itable = Table::new(); let mut itable = Table::new();
itable.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR); itable.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
@@ -40,6 +48,10 @@ impl Interactive {
Self::process_group_action(group, gindex, result.len(), itable); Self::process_group_action(group, gindex, result.len(), itable);
}); });
if printed_count.load(std::sync::atomic::Ordering::Relaxed) < 1 {
println!("No duplicates found matching your search criteria.");
}
Ok(()) Ok(())
} }