diff --git a/Cargo.lock b/Cargo.lock index 1912520..ab8bb68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -389,9 +389,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.2.6" +version = "4.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d70680e56dc65cb226c361aaa4e4a16d1f7e082bfed9ffceaee39c2012384ec" +checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" dependencies = [ "clap_builder", "clap_derive", @@ -400,9 +400,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.6" +version = "4.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fad499d5e07338414687350c5fdb82b1ab0001e9b26aa6275deccb684b14164" +checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" dependencies = [ "anstream", "anstyle", @@ -744,13 +744,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.15", ] [[package]] @@ -1827,9 +1827,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b64f40e5e03e0d54f03845c8197d0291253cdbedfb1cb46b13c2c117554a9f4c" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" [[package]] name = "locale_config" @@ -2293,9 +2293,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "png" @@ -2633,9 +2633,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.18" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbfc1d1c7c40c01715f47d71444744a81669ca84e8b63e25a55e169b1f86433" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ "bitflags 1.3.2", "errno", @@ -2708,18 +2708,18 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.160" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.160" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" dependencies = [ "proc-macro2", "quote", diff --git a/czkawka_core/src/common.rs b/czkawka_core/src/common.rs index 97f8d33..5752455 100644 --- a/czkawka_core/src/common.rs +++ b/czkawka_core/src/common.rs @@ -22,6 +22,7 @@ use libheif_rs::{ColorSpace, HeifContext, RgbChroma}; use crate::common_dir_traversal::{CheckingMethod, ProgressData}; use crate::common_directory::Directories; use crate::common_items::ExcludedItems; +use crate::common_traits::ResultEntry; static NUMBER_OF_THREADS: state::Storage = state::Storage::new(); @@ -364,6 +365,25 @@ pub fn check_folder_children( dir_result.push(next_folder); } +#[must_use] +pub fn filter_reference_folders_generic(entries_to_check: Vec>, directories: &Directories) -> Vec<(T, Vec)> +where + T: ResultEntry, +{ + entries_to_check + .into_iter() + .filter_map(|vec_file_entry| { + let (mut files_from_referenced_folders, normal_files): (Vec<_>, Vec<_>) = vec_file_entry.into_iter().partition(|e| directories.is_referenced_directory(e.get_path())); + + if files_from_referenced_folders.is_empty() || normal_files.is_empty() { + None + } else { + Some((files_from_referenced_folders.pop().unwrap(), normal_files)) + } + }) + .collect::)>>() +} + pub fn prepare_thread_handler_common( progress_sender: Option<&UnboundedSender>, progress_thread_run: &Arc, diff --git a/czkawka_core/src/common_directory.rs b/czkawka_core/src/common_directory.rs index e633748..3a6d177 100644 --- a/czkawka_core/src/common_directory.rs +++ b/czkawka_core/src/common_directory.rs @@ -305,6 +305,11 @@ impl Directories { true } + #[must_use] + pub fn is_referenced_directory(&self, path: &Path) -> bool { + self.reference_directories.iter().any(|e| path.starts_with(e)) + } + /// Checks whether a specified directory is excluded from searching pub fn is_excluded(&self, path: impl AsRef) -> bool { let path = path.as_ref(); diff --git a/czkawka_core/src/common_traits.rs b/czkawka_core/src/common_traits.rs index 2e03fed..7c64b4c 100644 --- a/czkawka_core/src/common_traits.rs +++ b/czkawka_core/src/common_traits.rs @@ -1,3 +1,5 @@ +use std::path::Path; + pub trait DebugPrint { fn debug_print(&self); } @@ -9,3 +11,7 @@ pub trait SaveResults { pub trait PrintResults { fn print_results(&self); } + +pub trait ResultEntry { + fn get_path(&self) -> &Path; +} diff --git a/czkawka_core/src/same_music.rs b/czkawka_core/src/same_music.rs index 8f985a6..3a7b5fc 100644 --- a/czkawka_core/src/same_music.rs +++ b/czkawka_core/src/same_music.rs @@ -22,8 +22,8 @@ use symphonia::core::io::MediaSourceStream; use symphonia::core::meta::MetadataOptions; use symphonia::core::probe::Hint; -use crate::common::open_cache_folder; use crate::common::{create_crash_message, prepare_thread_handler_common, send_info_and_wait_for_ending_all_threads, AUDIO_FILES_EXTENSIONS}; +use crate::common::{filter_reference_folders_generic, open_cache_folder}; use crate::common_dir_traversal::{CheckingMethod, DirTraversalBuilder, DirTraversalResult, FileEntry, ProgressData}; use crate::common_directory::Directories; use crate::common_extensions::Extensions; @@ -73,6 +73,12 @@ pub struct MusicEntry { pub bitrate: u32, } +impl ResultEntry for MusicEntry { + fn get_path(&self) -> &Path { + &self.path + } +} + impl FileEntry { fn to_music_entry(&self) -> MusicEntry { MusicEntry { @@ -650,9 +656,8 @@ impl SameMusic { send_info_and_wait_for_ending_all_threads(&progress_thread_run, progress_thread_handle); return false; } - + let old_duplicates_len = old_duplicates.len(); for vec_file_entry in old_duplicates { - atomic_counter.fetch_add(1, Ordering::Relaxed); let mut hash_map: BTreeMap> = Default::default(); for file_entry in vec_file_entry { if file_entry.bitrate != 0 { @@ -668,6 +673,7 @@ impl SameMusic { } } } + atomic_counter.fetch_add(old_duplicates_len, Ordering::Relaxed); old_duplicates = new_duplicates; } @@ -675,7 +681,9 @@ impl SameMusic { self.duplicated_music_entries = old_duplicates; - self.filter_reference_folders(); + if self.use_reference_folders { + self.duplicated_music_entries_referenced = filter_reference_folders_generic(mem::take(&mut self.duplicated_music_entries), &self.directories); + } if self.use_reference_folders { for (_fe, vector) in &self.duplicated_music_entries_referenced { @@ -695,6 +703,22 @@ impl SameMusic { true } + // fn split_fingerprints_to_check(&self) -> (Vec, Vec) { + // let mut base_files: Vec = Vec::new(); + // let mut files_to_compare: Vec = Vec::new(); + // + // if self.use_reference_folders { + // // base_files = + // } else { + // base_files = self.music_entries.clone(); + // files_to_compare = self.music_entries.clone(); + // } + // + // (base_files, files_to_compare) + // } + + // fn compare_improved(&mut self, stop_receiver: Option<&Receiver<()>>, atomic_counter: &Arc) -> Option>> {} + fn compare_fingerprints(&mut self, stop_receiver: Option<&Receiver<()>>, atomic_counter: &Arc) -> Option>> { // TODO do optimization // Multithreading @@ -780,7 +804,10 @@ impl SameMusic { // TODO fill this with proper values self.duplicated_music_entries = duplicated_music_entries; // Use - self.filter_reference_folders(); + + if self.use_reference_folders { + self.duplicated_music_entries_referenced = filter_reference_folders_generic(mem::take(&mut self.duplicated_music_entries), &self.directories); + } if self.use_reference_folders { for (_fe, vector) in &self.duplicated_music_entries_referenced { @@ -808,8 +835,8 @@ impl SameMusic { approximate_comparison: bool, ) -> Vec> { let mut new_duplicates: Vec<_> = Default::default(); + let old_duplicates_len = old_duplicates.len(); for vec_file_entry in old_duplicates { - atomic_counter.fetch_add(1, Ordering::Relaxed); let mut hash_map: BTreeMap> = Default::default(); for file_entry in vec_file_entry { let mut thing = get_item(&file_entry).trim().to_lowercase(); @@ -826,40 +853,11 @@ impl SameMusic { } } } + atomic_counter.fetch_add(old_duplicates_len, Ordering::Relaxed); new_duplicates } - fn filter_reference_folders(&mut self) { - if !self.use_reference_folders { - return; - } - - let mut similar_vector = Default::default(); - mem::swap(&mut self.duplicated_music_entries, &mut similar_vector); - let reference_directories = self.directories.reference_directories.clone(); - self.duplicated_music_entries_referenced = similar_vector - .into_iter() - .filter_map(|vec_file_entry| { - let mut files_from_referenced_folders = Vec::new(); - let mut normal_files = Vec::new(); - for file_entry in vec_file_entry { - if reference_directories.iter().any(|e| file_entry.path.starts_with(e)) { - files_from_referenced_folders.push(file_entry); - } else { - normal_files.push(file_entry); - } - } - - if files_from_referenced_folders.is_empty() || normal_files.is_empty() { - None - } else { - Some((files_from_referenced_folders.pop().unwrap(), normal_files)) - } - }) - .collect::)>>(); - } - pub fn set_minimal_file_size(&mut self, minimal_file_size: u64) { self.minimal_file_size = match minimal_file_size { 0 => 1,