From 909967dcd8c9d918b5a60756927d6257b63299df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mikrut?= <41945903+qarmin@users.noreply.github.com> Date: Fri, 6 Aug 2021 16:40:43 +0200 Subject: [PATCH] Update BKtree and blake3 and add new grouping algorithm (#405) * Update BKtree and blake3 * Add new algorithm for similar images * Improve algorithm of grouping similar images --- Cargo.lock | 137 ++++++++++------------- README.md | 8 +- czkawka_cli/src/commands.rs | 8 +- czkawka_core/Cargo.toml | 4 +- czkawka_core/src/similar_images.rs | 120 ++++++++++---------- czkawka_gui/src/connect_button_search.rs | 2 +- 6 files changed, 139 insertions(+), 140 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 910bd1b..f9aec43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,9 +59,9 @@ checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" [[package]] name = "arrayvec" -version = "0.5.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd" [[package]] name = "atk" @@ -156,22 +156,25 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bk-tree" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5488039ea2c6de8668351415e39a0218a8955bffadcff0cf01d1293a20854584" +checksum = "6121f6e107e94d717b5ca2631d56e7c2ed1542a21b2eb87b4bda1d6c1420ef3f" +dependencies = [ + "fnv", + "triple_accel", +] [[package]] name = "blake3" -version = "0.3.8" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b64485778c4f16a6a5a9d335e80d449ac6c70cdd6a06d2af18a6f6f775a125b3" +checksum = "dcd555c66291d5f836dbb6883b48660ece810fe25a31f3bdfb911945dff2691f" dependencies = [ "arrayref", "arrayvec", "cc", - "cfg-if 0.1.10", + "cfg-if", "constant_time_eq", - "crypto-mac", "digest", ] @@ -270,19 +273,13 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a1d12766bbdd5d44caab5df04a9bffec9cd855a1b44b15de5665d70c085f94" +checksum = "b412e83326147c2bb881f8b40edfbf9905b9b8abaebd0e47ca190ba62fda8f0e" dependencies = [ "smallvec", ] -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -412,7 +409,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -421,17 +418,17 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] @@ -442,7 +439,7 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", "lazy_static", "memoffset", @@ -455,20 +452,10 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "lazy_static", ] -[[package]] -name = "crypto-mac" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" -dependencies = [ - "generic-array", - "subtle", -] - [[package]] name = "czkawka_cli" version = "3.1.0" @@ -590,7 +577,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "dirs-sys-next", ] @@ -627,7 +614,7 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crc32fast", "libc", "miniz_oxide 0.4.4", @@ -807,7 +794,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi", ] @@ -1066,7 +1053,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -1100,9 +1087,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "972f5ae5d1cb9c6ae417789196c803205313edde988685da5e3aae0827b9e7fd" +checksum = "f5ca711fd837261e14ec9e674f092cbb931d3fa1482b017ae59328ddc6f3212b" dependencies = [ "libc", ] @@ -1118,9 +1105,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.51" +version = "0.3.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062" +checksum = "ce791b7ca6638aae45be056e068fc756d871eb3b3b10b8efa62d1c9cec616752" dependencies = [ "wasm-bindgen", ] @@ -1160,7 +1147,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "winapi", ] @@ -1179,7 +1166,7 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -1325,7 +1312,7 @@ checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" dependencies = [ "bitflags", "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", ] @@ -1413,9 +1400,9 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5adf0198d427ee515335639f275e806ca01acf9f07d7cf14bb36a10532a6169" +checksum = "ee2c8fd66061a707503d515639b8af10fd3807a5b5ee6959f7ff1bd303634bd5" dependencies = [ "derivative", "num_enum_derive", @@ -1423,9 +1410,9 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1def5a3f69d4707d8a040b12785b98029a39e8c610ae685c7f6265669767482" +checksum = "474fd1d096da3ad17084694eebed40ba09c4a36c5255cd772bd8b98859cc562e" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro2", @@ -1523,7 +1510,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "instant", "libc", "redox_syscall", @@ -1728,9 +1715,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ "bitflags", ] @@ -1860,18 +1847,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.126" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.126" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" dependencies = [ "proc-macro2", "quote", @@ -1973,12 +1960,6 @@ dependencies = [ "syn", ] -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - [[package]] name = "syn" version = "1.0.74" @@ -2014,7 +1995,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "rand", "redox_syscall", @@ -2122,6 +2103,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "triple_accel" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622b09ce2fe2df4618636fb92176d205662f59803f39e70d1c333393082de96c" + [[package]] name = "typenum" version = "1.13.0" @@ -2189,19 +2176,19 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "wasm-bindgen" -version = "0.2.74" +version = "0.2.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" +checksum = "b608ecc8f4198fe8680e2ed18eccab5f0cd4caaf3d83516fa5fb2e927fda2586" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.74" +version = "0.2.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" +checksum = "580aa3a91a63d23aac5b6b267e2d13cb4f363e31dce6c352fca4752ae12e479f" dependencies = [ "bumpalo", "lazy_static", @@ -2214,9 +2201,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.74" +version = "0.2.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" +checksum = "171ebf0ed9e1458810dfcb31f2e766ad6b3a89dbda42d8901f2b268277e5f09c" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2224,9 +2211,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.74" +version = "0.2.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" +checksum = "6c2657dd393f03aa2a659c25c6ae18a13a4048cebd220e147933ea837efc589f" dependencies = [ "proc-macro2", "quote", @@ -2237,15 +2224,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.74" +version = "0.2.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" +checksum = "2e0c4a743a309662d45f4ede961d7afa4ba4131a59a639f29b0069c3798bbcc2" [[package]] name = "web-sys" -version = "0.3.51" +version = "0.3.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582" +checksum = "01c70a82d842c9979078c772d4a1344685045f1a5628f677c2b2eab4dd7d2696" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/README.md b/README.md index 26529f0..a3a1a26 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ You can help by creating: You can also help by doing different things: - Creating text articles - [LinuxUprising](https://www.linuxuprising.com/2021/03/find-and-remove-duplicate-files-similar.html) or [Ubunlog](https://ubunlog.com/en/czkawka-finds-and-removes-empty-and-broken-duplicate-files/) - Adding Czkawka to repositories - [Alpine Linux](https://pkgs.alpinelinux.org/packages?name=czkawka&branch=edge) or [NixOS](https://github.com/NixOS/nixpkgs/pull/116441) or [OpenMandriva](https://github.com/OpenMandrivaAssociation/czkawka) -- Creating videos - [Tutorial Spanish 1](https://www.youtube.com/watch?v=tALYBsJAYwE) or [Tutorial Spanish 2](https://www.youtube.com/watch?v=V9x-pHJRmKY) +- Creating videos - [First Video](https://www.youtube.com/watch?v=CWlRiTD4vDc) or [Tutorial Spanish](https://www.youtube.com/watch?v=V9x-pHJRmKY) - Recommending it to others ## Name @@ -159,5 +159,11 @@ The program is completely free to use. "Gratis to uczciwa cena" - "Free is a fair price" +## Thanks + +Big thanks to Pádraig Brady, creator of fantastic FSlint, because without his work I wouldn't create this tool. + +Thanks also to all the people who create patches for this program, make it available on other systems, create videos, articles about it etc. + ## Donations If you are using the app, I would appreciate a donation for its further development, which can be done [here](https://github.com/sponsors/qarmin). diff --git a/czkawka_cli/src/commands.rs b/czkawka_cli/src/commands.rs index 06064c9..e3a98c1 100644 --- a/czkawka_cli/src/commands.rs +++ b/czkawka_cli/src/commands.rs @@ -289,10 +289,10 @@ fn parse_delete_method(src: &str) -> Result { // TODO For now it looks different fn parse_similar_images_similarity(src: &str) -> Result { match src.to_ascii_lowercase().replace('_', "").as_str() { - "minimal" => Ok(Similarity::Similar(5)), - "verysmall" => Ok(Similarity::Similar(4)), - "small" => Ok(Similarity::Similar(3)), - "medium" => Ok(Similarity::Similar(2)), + "minimal" => Ok(Similarity::Similar(12)), + "verysmall" => Ok(Similarity::Similar(8)), + "small" => Ok(Similarity::Similar(5)), + "medium" => Ok(Similarity::Similar(3)), "high" => Ok(Similarity::Similar(1)), "veryhigh" => Ok(Similarity::Similar(0)), _ => Err("Couldn't parse the delete method (allowed: verysmall, small, medium, high, veryhigh)"), diff --git a/czkawka_core/Cargo.toml b/czkawka_core/Cargo.toml index 8ca560d..bce0b08 100644 --- a/czkawka_core/Cargo.toml +++ b/czkawka_core/Cargo.toml @@ -19,7 +19,7 @@ directories-next = "2.0.0" # Needed by similar images img_hash = "3.2.0" -bk-tree = "0.3.0" # Do not update. Updating broke of searching for similar hashes +bk-tree = "0.4.0" image = "0.23.14" hamming = "0.1.3" @@ -35,7 +35,7 @@ zip = "0.5.13" rodio = { version = "0.14.0", optional = true } # Hashes -blake3 = "0.3.8" +blake3 = "1.0.0" crc32fast = "1.2.1" xxhash-rust = { version = "0.8.2", features = ["xxh3"] } diff --git a/czkawka_core/src/similar_images.rs b/czkawka_core/src/similar_images.rs index c3448d2..fb6abf5 100644 --- a/czkawka_core/src/similar_images.rs +++ b/czkawka_core/src/similar_images.rs @@ -10,7 +10,7 @@ use humansize::{file_size_opts as options, FileSize}; use image::GenericImageView; use img_hash::HasherConfig; use rayon::prelude::*; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::fs::OpenOptions; use std::fs::{File, Metadata}; use std::io::Write; @@ -38,9 +38,11 @@ pub struct ProgressData { #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)] pub enum Similarity { None, - Similar(u64), + Similar(u32), } +const MAX_SIMILARITY: u32 = 12; + #[derive(Clone, Debug)] pub struct FileEntry { pub path: PathBuf, @@ -55,14 +57,13 @@ pub struct FileEntry { struct Hamming; impl bk_tree::Metric for Hamming { - fn distance(&self, a: &Node, b: &Node) -> u64 { - hamming::distance_fast(a, b).unwrap() as u64 + fn distance(&self, a: &Node, b: &Node) -> u32 { + hamming::distance_fast(a, b).unwrap() as u32 } - // // TODO Probably needs to be implemented - // fn threshold_distance(&self, _a: &Node, _b: &Node, _threshold: u32) -> Option { - // None - // } + fn threshold_distance(&self, a: &Node, b: &Node, _threshold: u32) -> Option { + Some(self.distance(a, b)) + } } /// Struct to store most basics info about all folder @@ -454,61 +455,69 @@ impl SimilarImages { Common::print_time(hash_map_modification, SystemTime::now(), "sort_images - saving data to files".to_string()); let hash_map_modification = SystemTime::now(); - let similarity: u64 = match self.similarity { + let similarity: u32 = match self.similarity { Similarity::Similar(k) => k, _ => panic!(), }; - // TODO - // Now is A is similar to B with VeryHigh and C with Medium - // And D is similar with C with High - // And Similarity is set to Medium(or lower) - // And A is checked before D - // Then C is shown that is similar group A, not D - // TODO // Maybe also add here progress report - let mut new_vector: Vec> = Vec::new(); - let mut non_cached_files_to_check = self.image_hashes.clone(); - for (hash, vec_file_entry) in &self.image_hashes { + let mut collected_similar_images: BTreeMap> = Default::default(); + + let mut available_hashes = self.image_hashes.clone(); + let mut this_time_check_hashes; + let mut master_of_group: BTreeSet = Default::default(); // Lista wszystkich głównych hashy, które odpowiadają za porównywanie + + for current_similarity in 0..=MAX_SIMILARITY { + this_time_check_hashes = available_hashes.clone(); + if stop_receiver.is_some() && stop_receiver.unwrap().try_recv().is_ok() { return false; } - if !non_cached_files_to_check.contains_key(hash) { - continue; - } - non_cached_files_to_check.remove(hash); - let vector_with_found_similar_hashes = self.bktree.find(hash, similarity).collect::>(); - if vector_with_found_similar_hashes.len() == 1 && vec_file_entry.len() == 1 { - // This one picture doesn't have similar pictures, so there is no go - continue; - } + for (hash, vec_file_entry) in this_time_check_hashes.iter() { + let vector_with_found_similar_hashes = self + .bktree + .find(hash, similarity) + .filter(|r| (r.0 == current_similarity) && !master_of_group.contains(r.1) && available_hashes.contains_key(r.1)) + .collect::>(); - let mut vector_of_similar_images: Vec = vec_file_entry - .iter() - .map(|fe| FileEntry { - path: fe.path.clone(), - size: fe.size, - dimensions: fe.dimensions.clone(), - modified_date: fe.modified_date, - hash: fe.hash, - similarity: Similarity::Similar(0), - }) - .collect(); - - for (similarity, similar_hash) in vector_with_found_similar_hashes.iter() { - if *similarity == 0 && hash == *similar_hash { - // This was already read before + // Not found any hash with specific distance + if vector_with_found_similar_hashes.is_empty() { continue; - } else if hash == *similar_hash { - panic!("I'm not sure if same hash can have distance > 0"); } - if let Some(vec_file_entry) = non_cached_files_to_check.get(*similar_hash) { - vector_of_similar_images.append( - &mut (vec_file_entry + // This one picture doesn't have similar pictures except self in similarity 0 + if current_similarity == 0 && vector_with_found_similar_hashes.len() == 1 { + continue; + } + + // Jeśli jeszcze nie dodał, to dodaje teraz grupę główną do już obrobionych + if !master_of_group.contains(hash) { + master_of_group.insert(*hash); + collected_similar_images.insert(*hash, Vec::new()); + + let mut things: Vec = vec_file_entry + .iter() + .map(|fe| FileEntry { + path: fe.path.clone(), + size: fe.size, + dimensions: fe.dimensions.clone(), + modified_date: fe.modified_date, + hash: fe.hash, + similarity: Similarity::Similar(0), + }) + .collect(); + collected_similar_images.get_mut(hash).unwrap().append(&mut things); + } + + // Since we checked hash, we don't need to check it again + if current_similarity != 0 { + vector_with_found_similar_hashes.iter().for_each(|e| { + let mut things: Vec = available_hashes + .get_mut(e.1) + .unwrap() .iter() .map(|fe| FileEntry { path: fe.path.clone(), @@ -516,20 +525,17 @@ impl SimilarImages { dimensions: fe.dimensions.clone(), modified_date: fe.modified_date, hash: [0; 8], - similarity: Similarity::Similar(*similarity), + similarity: Similarity::Similar(current_similarity), }) - .collect::>()), - ); - non_cached_files_to_check.remove(*similar_hash); + .collect::>(); + collected_similar_images.get_mut(hash).unwrap().append(&mut things); + available_hashes.remove(e.1); + }); } } - if vector_of_similar_images.len() > 1 { - // Not sure why it may happens - new_vector.push((*vector_of_similar_images).to_owned()); - } } - self.similar_vectors = new_vector; + self.similar_vectors = collected_similar_images.values().cloned().collect(); Common::print_time(hash_map_modification, SystemTime::now(), "sort_images - selecting data from BtreeMap".to_string()); diff --git a/czkawka_gui/src/connect_button_search.rs b/czkawka_gui/src/connect_button_search.rs index 3ddc215..acf3b4e 100644 --- a/czkawka_gui/src/connect_button_search.rs +++ b/czkawka_gui/src/connect_button_search.rs @@ -265,7 +265,7 @@ pub fn connect_button_search( let minimal_file_size = entry_similar_images_minimal_size.text().as_str().parse::().unwrap_or(1024 * 16); - let similarity = similar_images::Similarity::Similar(scale_similarity.value() as u64); + let similarity = similar_images::Similarity::Similar(scale_similarity.value() as u32); let futures_sender_similar_images = futures_sender_similar_images.clone(); // Find similar images