1
0
Fork 0
mirror of synced 2024-05-17 19:03:08 +12:00

Crossbeam instead futures

This commit is contained in:
Rafał Mikrut 2023-10-22 22:55:20 +02:00
parent 6d8fe135ce
commit 674d4798f7
21 changed files with 114 additions and 147 deletions

19
Cargo.lock generated
View file

@ -1263,7 +1263,6 @@ dependencies = [
"directories-next",
"ffmpeg_cmdline_utils",
"fun_time",
"futures",
"hamming",
"handsome_logger",
"humansize",
@ -1304,7 +1303,6 @@ dependencies = [
"directories-next",
"fs_extra",
"fun_time",
"futures",
"gdk4",
"glib",
"gtk4",
@ -2000,21 +1998,6 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "futures"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.28"
@ -2022,7 +2005,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
@ -2092,7 +2074,6 @@ version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",

View file

@ -28,9 +28,6 @@ hamming = "0.1"
bitflags = "2.4"
lofty = "0.16"
# Futures - needed by async progress sender
futures = "0.3.28"
# Needed by broken files
zip = { version = "0.6", features = ["aes-crypto", "bzip2", "deflate", "time"], default-features = false }
audio_checker = "0.1"

View file

@ -5,9 +5,8 @@ use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
use crossbeam_channel::Receiver;
use crossbeam_channel::{Receiver, Sender};
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use log::debug;
use mime_guess::get_mime_extensions;
use rayon::prelude::*;
@ -195,7 +194,7 @@ impl BadExtensions {
}
#[fun_time(message = "find_bad_extensions_files", level = "info")]
pub fn find_bad_extensions_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
pub fn find_bad_extensions_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.check_files(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -209,7 +208,7 @@ impl BadExtensions {
}
#[fun_time(message = "check_files", level = "debug")]
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let result = DirTraversalBuilder::new()
.root_dirs(self.common_data.directories.included_directories.clone())
.group_by(|_fe| ())
@ -239,7 +238,7 @@ impl BadExtensions {
}
#[fun_time(message = "look_for_bad_extensions_files", level = "debug")]
fn look_for_bad_extensions_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn look_for_bad_extensions_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let (progress_thread_handle, progress_thread_run, atomic_counter, check_was_stopped) =
prepare_thread_handler_common(progress_sender, 1, 1, self.files_to_check.len(), CheckingMethod::None, self.get_cd().tool_type);

View file

@ -6,9 +6,8 @@ use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use crossbeam_channel::Receiver;
use crossbeam_channel::{Receiver, Sender};
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use humansize::{format_size, BINARY};
use log::debug;
use rayon::prelude::*;
@ -57,7 +56,7 @@ impl BigFile {
}
#[fun_time(message = "find_big_files", level = "info")]
pub fn find_big_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
pub fn find_big_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.look_for_big_files(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -68,7 +67,7 @@ impl BigFile {
}
#[fun_time(message = "look_for_big_files", level = "debug")]
fn look_for_big_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn look_for_big_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let mut folders_to_check: Vec<PathBuf> = Vec::with_capacity(1024 * 2); // This should be small enough too not see to big difference and big enough to store most of paths without needing to resize vector
let mut old_map: BTreeMap<u64, Vec<FileEntry>> = Default::default();

View file

@ -7,9 +7,8 @@ use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::{fs, mem, panic};
use crossbeam_channel::Receiver;
use crossbeam_channel::{Receiver, Sender};
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use log::debug;
use pdf::file::FileOptions;
use pdf::object::ParseOptions;
@ -93,7 +92,7 @@ impl BrokenFiles {
}
#[fun_time(message = "find_broken_files", level = "info")]
pub fn find_broken_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
pub fn find_broken_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.check_files(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -108,7 +107,7 @@ impl BrokenFiles {
}
#[fun_time(message = "check_files", level = "debug")]
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let mut folders_to_check: Vec<PathBuf> = Vec::with_capacity(1024 * 2); // This should be small enough too not see to big difference and big enough to store most of paths without needing to resize vector
// Add root folders for finding
@ -347,7 +346,7 @@ impl BrokenFiles {
}
#[fun_time(message = "look_for_broken_files", level = "debug")]
fn look_for_broken_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn look_for_broken_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let (loaded_hash_map, records_already_cached, non_cached_files_to_check) = self.load_cache();
let (progress_thread_handle, progress_thread_run, atomic_counter, _check_was_stopped) =

View file

@ -10,9 +10,9 @@ use std::{fs, thread};
#[cfg(feature = "heif")]
use anyhow::Result;
use crossbeam_channel::Sender;
use directories_next::ProjectDirs;
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use handsome_logger::{ColorChoice, ConfigBuilder, TerminalMode};
use image::{DynamicImage, ImageBuffer, Rgb};
use imagepipe::{ImageSource, Pipeline};
@ -460,7 +460,7 @@ where
}
pub fn prepare_thread_handler_common(
progress_sender: Option<&UnboundedSender<ProgressData>>,
progress_sender: Option<&Sender<ProgressData>>,
current_stage: u8,
max_stage: u8,
max_value: usize,
@ -480,7 +480,7 @@ pub fn prepare_thread_handler_common(
loop {
if time_since_last_send.elapsed().unwrap().as_millis() > SEND_PROGRESS_DATA_TIME_BETWEEN as u128 {
progress_send
.unbounded_send(ProgressData {
.send(ProgressData {
checking_method,
current_stage,
max_stage,

View file

@ -5,9 +5,8 @@ use std::path::{Path, PathBuf};
use std::sync::atomic::Ordering;
use std::time::UNIX_EPOCH;
use crossbeam_channel::Receiver;
use crossbeam_channel::{Receiver, Sender};
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use log::debug;
use rayon::prelude::*;
use serde::{Deserialize, Serialize};
@ -136,7 +135,7 @@ pub struct DirTraversalBuilder<'a, 'b, F> {
group_by: Option<F>,
root_dirs: Vec<PathBuf>,
stop_receiver: Option<&'a Receiver<()>>,
progress_sender: Option<&'b UnboundedSender<ProgressData>>,
progress_sender: Option<&'b Sender<ProgressData>>,
minimal_file_size: Option<u64>,
maximal_file_size: Option<u64>,
checking_method: CheckingMethod,
@ -153,7 +152,7 @@ pub struct DirTraversal<'a, 'b, F> {
group_by: F,
root_dirs: Vec<PathBuf>,
stop_receiver: Option<&'a Receiver<()>>,
progress_sender: Option<&'b UnboundedSender<ProgressData>>,
progress_sender: Option<&'b Sender<ProgressData>>,
recursive_search: bool,
directories: Directories,
excluded_items: ExcludedItems,
@ -204,7 +203,7 @@ impl<'a, 'b, F> DirTraversalBuilder<'a, 'b, F> {
self
}
pub fn progress_sender(mut self, progress_sender: Option<&'b UnboundedSender<ProgressData>>) -> Self {
pub fn progress_sender(mut self, progress_sender: Option<&'b Sender<ProgressData>>) -> Self {
self.progress_sender = progress_sender;
self
}

View file

@ -10,9 +10,8 @@ use std::path::Path;
use std::sync::atomic::Ordering;
use std::{fs, mem};
use crossbeam_channel::Receiver;
use crossbeam_channel::{Receiver, Sender};
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use humansize::{format_size, BINARY};
use log::debug;
use rayon::prelude::*;
@ -111,7 +110,7 @@ impl DuplicateFinder {
}
#[fun_time(message = "find_duplicates", level = "info")]
pub fn find_duplicates(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
pub fn find_duplicates(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) {
self.optimize_dirs_before_start();
self.common_data.use_reference_folders = !self.common_data.directories.reference_directories.is_empty();
@ -151,7 +150,7 @@ impl DuplicateFinder {
}
#[fun_time(message = "check_files_name", level = "debug")]
fn check_files_name(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_files_name(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let group_by_func = if self.case_sensitive_name_comparison {
|fe: &FileEntry| fe.path.file_name().unwrap().to_string_lossy().to_string()
} else {
@ -226,7 +225,7 @@ impl DuplicateFinder {
}
#[fun_time(message = "check_files_size_name", level = "debug")]
fn check_files_size_name(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_files_size_name(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let group_by_func = if self.case_sensitive_name_comparison {
|fe: &FileEntry| (fe.size, fe.path.file_name().unwrap().to_string_lossy().to_string())
} else {
@ -303,7 +302,7 @@ impl DuplicateFinder {
}
#[fun_time(message = "check_files_size", level = "debug")]
fn check_files_size(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_files_size(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let max_stage = match self.check_method {
CheckingMethod::Size => 0,
CheckingMethod::Hash => MAX_STAGE,
@ -491,7 +490,7 @@ impl DuplicateFinder {
fn prehashing(
&mut self,
stop_receiver: Option<&Receiver<()>>,
progress_sender: Option<&UnboundedSender<ProgressData>>,
progress_sender: Option<&Sender<ProgressData>>,
pre_checked_map: &mut BTreeMap<u64, Vec<FileEntry>>,
) -> Option<()> {
let check_type = self.hash_type;
@ -679,12 +678,7 @@ impl DuplicateFinder {
}
#[fun_time(message = "full_hashing", level = "debug")]
fn full_hashing(
&mut self,
stop_receiver: Option<&Receiver<()>>,
progress_sender: Option<&UnboundedSender<ProgressData>>,
pre_checked_map: BTreeMap<u64, Vec<FileEntry>>,
) -> Option<()> {
fn full_hashing(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>, pre_checked_map: BTreeMap<u64, Vec<FileEntry>>) -> Option<()> {
let (progress_thread_handle, progress_thread_run, _atomic_counter, _check_was_stopped) =
prepare_thread_handler_common(progress_sender, 4, MAX_STAGE, 0, self.check_method, self.common_data.tool_type);
@ -805,7 +799,7 @@ impl DuplicateFinder {
}
#[fun_time(message = "check_files_hash", level = "debug")]
fn check_files_hash(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_files_hash(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
assert_eq!(self.check_method, CheckingMethod::Hash);
let mut pre_checked_map: BTreeMap<u64, Vec<FileEntry>> = Default::default();

View file

@ -2,9 +2,8 @@ use std::fs;
use std::io::prelude::*;
use crossbeam_channel::Receiver;
use crossbeam_channel::{Receiver, Sender};
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use log::debug;
use crate::common_dir_traversal::{DirTraversalBuilder, DirTraversalResult, FileEntry, ProgressData, ToolType};
@ -41,7 +40,7 @@ impl EmptyFiles {
}
#[fun_time(message = "find_empty_files", level = "info")]
pub fn find_empty_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
pub fn find_empty_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.check_files(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -52,7 +51,7 @@ impl EmptyFiles {
}
#[fun_time(message = "check_files", level = "debug")]
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let result = DirTraversalBuilder::new()
.root_dirs(self.common_data.directories.included_directories.clone())
.group_by(|_fe| ())

View file

@ -3,9 +3,8 @@ use std::fs;
use std::io::Write;
use std::path::PathBuf;
use crossbeam_channel::Receiver;
use crossbeam_channel::{Receiver, Sender};
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use log::debug;
use rayon::prelude::*;
@ -42,7 +41,7 @@ impl EmptyFolder {
}
#[fun_time(message = "find_empty_folders", level = "info")]
pub fn find_empty_folders(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
pub fn find_empty_folders(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.check_for_empty_folders(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -74,7 +73,7 @@ impl EmptyFolder {
}
#[fun_time(message = "check_for_empty_folders", level = "debug")]
fn check_for_empty_folders(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_for_empty_folders(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let result = DirTraversalBuilder::new()
.root_dirs(self.common_data.directories.included_directories.clone())
.group_by(|_fe| ())

View file

@ -2,9 +2,8 @@ use std::fs;
use std::io::prelude::*;
use crossbeam_channel::Receiver;
use crossbeam_channel::{Receiver, Sender};
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use log::debug;
use crate::common_dir_traversal::{Collect, DirTraversalBuilder, DirTraversalResult, ErrorType, FileEntry, ProgressData, ToolType};
@ -31,7 +30,7 @@ impl InvalidSymlinks {
}
#[fun_time(message = "find_invalid_links", level = "info")]
pub fn find_invalid_links(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
pub fn find_invalid_links(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.check_files(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -42,7 +41,7 @@ impl InvalidSymlinks {
}
#[fun_time(message = "check_files", level = "debug")]
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let result = DirTraversalBuilder::new()
.root_dirs(self.common_data.directories.included_directories.clone())
.group_by(|_fe| ())

View file

@ -9,9 +9,9 @@ use std::sync::Arc;
use std::{mem, panic};
use anyhow::Context;
use crossbeam_channel::Receiver;
use crossbeam_channel::{Receiver, Sender};
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use humansize::{format_size, BINARY};
use lofty::{read_from, AudioFile, ItemKey, TaggedFileExt};
use log::debug;
@ -137,7 +137,7 @@ impl SameMusic {
}
#[fun_time(message = "find_same_music", level = "info")]
pub fn find_same_music(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
pub fn find_same_music(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) {
self.optimize_dirs_before_start();
self.common_data.use_reference_folders = !self.common_data.directories.reference_directories.is_empty();
if !self.check_files(stop_receiver, progress_sender) {
@ -176,7 +176,7 @@ impl SameMusic {
}
#[fun_time(message = "check_files", level = "debug")]
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
if !self.common_data.allowed_extensions.using_custom_extensions() {
self.common_data.allowed_extensions.extend_allowed_extensions(AUDIO_FILES_EXTENSIONS);
} else {
@ -277,7 +277,7 @@ impl SameMusic {
}
#[fun_time(message = "calculate_fingerprint", level = "debug")]
fn calculate_fingerprint(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn calculate_fingerprint(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let (progress_thread_handle, progress_thread_run, _atomic_counter, _check_was_stopped) =
prepare_thread_handler_common(progress_sender, 1, MAX_STAGE_CONTENT, 0, self.check_type, self.common_data.tool_type);
@ -341,7 +341,7 @@ impl SameMusic {
}
#[fun_time(message = "read_tags", level = "debug")]
fn read_tags(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn read_tags(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let (progress_thread_handle, progress_thread_run, _atomic_counter, _check_was_stopped) =
prepare_thread_handler_common(progress_sender, 1, MAX_STAGE_TAGS, 0, self.check_type, self.common_data.tool_type);
@ -404,7 +404,7 @@ impl SameMusic {
}
#[fun_time(message = "check_for_duplicate_tags", level = "debug")]
fn check_for_duplicate_tags(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_for_duplicate_tags(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let (progress_thread_handle, progress_thread_run, atomic_counter, _check_was_stopped) =
prepare_thread_handler_common(progress_sender, 4, MAX_STAGE_TAGS, self.music_to_check.len(), self.check_type, self.common_data.tool_type);
@ -503,7 +503,7 @@ impl SameMusic {
true
}
#[fun_time(message = "read_tags_to_files_similar_by_content", level = "debug")]
fn read_tags_to_files_similar_by_content(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn read_tags_to_files_similar_by_content(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let groups_to_check = max(self.duplicated_music_entries.len(), self.duplicated_music_entries_referenced.len());
let (progress_thread_handle, progress_thread_run, atomic_counter, check_was_stopped) =
prepare_thread_handler_common(progress_sender, 5, MAX_STAGE_CONTENT, groups_to_check, self.check_type, self.common_data.tool_type);
@ -629,7 +629,7 @@ impl SameMusic {
}
#[fun_time(message = "check_for_duplicate_fingerprints", level = "debug")]
fn check_for_duplicate_fingerprints(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_for_duplicate_fingerprints(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let (base_files, files_to_compare) = self.split_fingerprints_to_check();
let (progress_thread_handle, progress_thread_run, atomic_counter, _check_was_stopped) =
prepare_thread_handler_common(progress_sender, 2, 3, base_files.len(), self.check_type, self.common_data.tool_type);

View file

@ -7,9 +7,9 @@ use std::time::SystemTime;
use std::{mem, panic};
use bk_tree::BKTree;
use crossbeam_channel::Receiver;
use crossbeam_channel::{Receiver, Sender};
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use humansize::{format_size, BINARY};
use image::GenericImageView;
use image_hasher::{FilterType, HashAlg, HasherConfig};
@ -125,7 +125,7 @@ impl SimilarImages {
}
#[fun_time(message = "find_similar_images", level = "info")]
pub fn find_similar_images(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
pub fn find_similar_images(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) {
self.optimize_dirs_before_start();
self.common_data.use_reference_folders = !self.common_data.directories.reference_directories.is_empty();
if !self.check_for_similar_images(stop_receiver, progress_sender) {
@ -145,7 +145,7 @@ impl SimilarImages {
}
#[fun_time(message = "check_for_similar_images", level = "debug")]
fn check_for_similar_images(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_for_similar_images(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let mut folders_to_check: Vec<PathBuf> = Vec::with_capacity(1024 * 2); // This should be small enough too not see to big difference and big enough to store most of paths without needing to resize vector
if !self.common_data.allowed_extensions.using_custom_extensions() {
@ -304,7 +304,7 @@ impl SimilarImages {
// - Join all hashes and save it to file
#[fun_time(message = "hash_images", level = "debug")]
fn hash_images(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn hash_images(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let (loaded_hash_map, records_already_cached, non_cached_files_to_check) = self.hash_images_load_cache();
let (progress_thread_handle, progress_thread_run, atomic_counter, check_was_stopped) =
@ -550,7 +550,7 @@ impl SimilarImages {
&mut self,
all_hashed_images: &HashMap<ImHash, Vec<FileEntry>>,
collected_similar_images: &mut HashMap<ImHash, Vec<FileEntry>>,
progress_sender: Option<&UnboundedSender<ProgressData>>,
progress_sender: Option<&Sender<ProgressData>>,
stop_receiver: Option<&Receiver<()>>,
tolerance: u32,
) -> bool {
@ -684,7 +684,7 @@ impl SimilarImages {
}
#[fun_time(message = "find_similar_hashes", level = "debug")]
fn find_similar_hashes(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn find_similar_hashes(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
if self.image_hashes.is_empty() {
return true;
}

View file

@ -5,10 +5,9 @@ use std::mem;
use std::path::{Path, PathBuf};
use std::sync::atomic::Ordering;
use crossbeam_channel::Receiver;
use crossbeam_channel::{Receiver, Sender};
use ffmpeg_cmdline_utils::FfmpegErrorKind::FfmpegNotFound;
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use humansize::{format_size, BINARY};
use rayon::prelude::*;
use serde::{Deserialize, Serialize};
@ -103,7 +102,7 @@ impl SimilarVideos {
}
#[fun_time(message = "find_similar_videos", level = "info")]
pub fn find_similar_videos(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
pub fn find_similar_videos(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) {
if !check_if_ffmpeg_is_installed() {
self.common_data.text_messages.errors.push(flc!("core_ffmpeg_not_found"));
#[cfg(target_os = "windows")]
@ -130,7 +129,7 @@ impl SimilarVideos {
}
#[fun_time(message = "check_for_similar_videos", level = "debug")]
fn check_for_similar_videos(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_for_similar_videos(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let mut folders_to_check: Vec<PathBuf> = Vec::with_capacity(1024 * 2); // This should be small enough too not see to big difference and big enough to store most of paths without needing to resize vector
if !self.common_data.allowed_extensions.using_custom_extensions() {
@ -266,7 +265,7 @@ impl SimilarVideos {
}
#[fun_time(message = "sort_videos", level = "debug")]
fn sort_videos(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn sort_videos(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let (loaded_hash_map, records_already_cached, non_cached_files_to_check) = self.load_cache_at_start();
let (progress_thread_handle, progress_thread_run, atomic_counter, check_was_stopped) =

View file

@ -6,9 +6,8 @@ use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use crossbeam_channel::Receiver;
use crossbeam_channel::{Receiver, Sender};
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use rayon::prelude::*;
use serde::Serialize;
@ -60,7 +59,7 @@ impl Temporary {
}
#[fun_time(message = "find_temporary_files", level = "info")]
pub fn find_temporary_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
pub fn find_temporary_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.check_files(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -71,7 +70,7 @@ impl Temporary {
}
#[fun_time(message = "check_files", level = "debug")]
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
let mut folders_to_check: Vec<PathBuf> = Vec::with_capacity(1024 * 2); // This should be small enough too not see to big difference and big enough to store most of paths without needing to resize vector
// Add root folders for finding

View file

@ -19,9 +19,6 @@ chrono = "0.4.31"
# Used for sending stop signal across threads
crossbeam-channel = "0.5.8"
# To get information about progress
futures = "0.3.28"
# For saving/loading config files to specific directories
directories-next = "2.0"

View file

@ -3,10 +3,9 @@ use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;
use crossbeam_channel::Receiver;
use crossbeam_channel::{Receiver, Sender};
use fun_time::fun_time;
use futures::channel::mpsc::UnboundedSender;
use glib::Sender;
use glib::Sender as glibSender;
use gtk4::prelude::*;
use gtk4::Grid;
@ -35,7 +34,7 @@ use crate::taskbar_progress::tbp_flags::TBPF_NOPROGRESS;
use crate::{flg, DEFAULT_MAXIMAL_FILE_SIZE, DEFAULT_MINIMAL_CACHE_SIZE, DEFAULT_MINIMAL_FILE_SIZE};
#[allow(clippy::too_many_arguments)]
pub fn connect_button_search(gui_data: &GuiData, glib_stop_sender: Sender<Message>, progress_sender: UnboundedSender<ProgressData>) {
pub fn connect_button_search(gui_data: &GuiData, glib_stop_sender: glibSender<Message>, progress_sender: Sender<ProgressData>) {
let buttons_array = gui_data.bottom_buttons.buttons_array.clone();
let buttons_search_clone = gui_data.bottom_buttons.buttons_search.clone();
let grid_progress_stages = gui_data.progress_window.grid_progress_stages.clone();
@ -284,9 +283,9 @@ fn duplicate_search(
gui_data: &GuiData,
loaded_common_items: LoadedCommonItems,
stop_receiver: Receiver<()>,
glib_stop_sender: Sender<Message>,
glib_stop_sender: glibSender<Message>,
grid_progress_stages: &Grid,
progress_data_sender: UnboundedSender<ProgressData>,
progress_data_sender: Sender<ProgressData>,
) {
grid_progress_stages.show();
@ -346,9 +345,9 @@ fn empty_files_search(
gui_data: &GuiData,
loaded_common_items: LoadedCommonItems,
stop_receiver: Receiver<()>,
glib_stop_sender: Sender<Message>,
glib_stop_sender: glibSender<Message>,
grid_progress_stages: &Grid,
progress_data_sender: UnboundedSender<ProgressData>,
progress_data_sender: Sender<ProgressData>,
) {
grid_progress_stages.hide();
@ -373,9 +372,9 @@ fn empty_directories_search(
gui_data: &GuiData,
loaded_common_items: LoadedCommonItems,
stop_receiver: Receiver<()>,
glib_stop_sender: Sender<Message>,
glib_stop_sender: glibSender<Message>,
grid_progress_stages: &Grid,
progress_data_sender: UnboundedSender<ProgressData>,
progress_data_sender: Sender<ProgressData>,
) {
grid_progress_stages.hide();
@ -397,9 +396,9 @@ fn big_files_search(
gui_data: &GuiData,
loaded_common_items: LoadedCommonItems,
stop_receiver: Receiver<()>,
glib_stop_sender: Sender<Message>,
glib_stop_sender: glibSender<Message>,
grid_progress_stages: &Grid,
progress_data_sender: UnboundedSender<ProgressData>,
progress_data_sender: Sender<ProgressData>,
) {
grid_progress_stages.hide();
@ -433,9 +432,9 @@ fn temporary_files_search(
gui_data: &GuiData,
loaded_common_items: LoadedCommonItems,
stop_receiver: Receiver<()>,
glib_stop_sender: Sender<Message>,
glib_stop_sender: glibSender<Message>,
grid_progress_stages: &Grid,
progress_data_sender: UnboundedSender<ProgressData>,
progress_data_sender: Sender<ProgressData>,
) {
grid_progress_stages.hide();
@ -459,9 +458,9 @@ fn same_music_search(
gui_data: &GuiData,
loaded_common_items: LoadedCommonItems,
stop_receiver: Receiver<()>,
glib_stop_sender: Sender<Message>,
glib_stop_sender: glibSender<Message>,
grid_progress_stages: &Grid,
progress_data_sender: UnboundedSender<ProgressData>,
progress_data_sender: Sender<ProgressData>,
show_dialog: &Arc<AtomicBool>,
) {
grid_progress_stages.show();
@ -561,9 +560,9 @@ fn broken_files_search(
gui_data: &GuiData,
loaded_common_items: LoadedCommonItems,
stop_receiver: Receiver<()>,
glib_stop_sender: Sender<Message>,
glib_stop_sender: glibSender<Message>,
grid_progress_stages: &Grid,
progress_data_sender: UnboundedSender<ProgressData>,
progress_data_sender: Sender<ProgressData>,
show_dialog: &Arc<AtomicBool>,
) {
grid_progress_stages.show();
@ -636,9 +635,9 @@ fn similar_image_search(
gui_data: &GuiData,
loaded_common_items: LoadedCommonItems,
stop_receiver: Receiver<()>,
glib_stop_sender: Sender<Message>,
glib_stop_sender: glibSender<Message>,
grid_progress_stages: &Grid,
progress_data_sender: UnboundedSender<ProgressData>,
progress_data_sender: Sender<ProgressData>,
) {
grid_progress_stages.show();
@ -698,9 +697,9 @@ fn similar_video_search(
gui_data: &GuiData,
loaded_common_items: LoadedCommonItems,
stop_receiver: Receiver<()>,
glib_stop_sender: Sender<Message>,
glib_stop_sender: glibSender<Message>,
grid_progress_stages: &Grid,
progress_data_sender: UnboundedSender<ProgressData>,
progress_data_sender: Sender<ProgressData>,
) {
grid_progress_stages.show();
@ -742,9 +741,9 @@ fn bad_symlinks_search(
gui_data: &GuiData,
loaded_common_items: LoadedCommonItems,
stop_receiver: Receiver<()>,
glib_stop_sender: Sender<Message>,
glib_stop_sender: glibSender<Message>,
grid_progress_stages: &Grid,
progress_data_sender: UnboundedSender<ProgressData>,
progress_data_sender: Sender<ProgressData>,
) {
grid_progress_stages.hide();
@ -769,9 +768,9 @@ fn bad_extensions_search(
gui_data: &GuiData,
loaded_common_items: LoadedCommonItems,
stop_receiver: Receiver<()>,
glib_stop_sender: Sender<Message>,
glib_stop_sender: glibSender<Message>,
grid_progress_stages: &Grid,
progress_data_sender: UnboundedSender<ProgressData>,
progress_data_sender: Sender<ProgressData>,
) {
grid_progress_stages.show();

View file

@ -1,9 +1,10 @@
use crossbeam_channel::Receiver;
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use futures::channel::mpsc::UnboundedReceiver;
use futures::StreamExt;
use std::time::Duration;
use glib::MainContext;
use gtk4::prelude::*;
use gtk4::ProgressBar;
@ -19,29 +20,35 @@ use crate::taskbar_progress::tbp_flags::TBPF_INDETERMINATE;
use crate::taskbar_progress::TaskbarProgress;
#[allow(clippy::too_many_arguments)]
pub fn connect_progress_window(gui_data: &GuiData, mut progress_receiver: UnboundedReceiver<ProgressData>) {
pub fn connect_progress_window(gui_data: &GuiData, progress_receiver: Receiver<ProgressData>) {
let main_context = MainContext::default();
let _guard = main_context.acquire().unwrap();
let gui_data = gui_data.clone();
let future = async move {
while let Some(item) = progress_receiver.next().await {
match item.tool_type {
ToolType::Duplicate => process_bar_duplicates(&gui_data, &item),
ToolType::EmptyFiles => process_bar_empty_files(&gui_data, &item),
ToolType::EmptyFolders => process_bar_empty_folder(&gui_data, &item),
ToolType::BigFile => process_bar_big_files(&gui_data, &item),
ToolType::SameMusic => process_bar_same_music(&gui_data, &item),
ToolType::SimilarImages => process_bar_similar_images(&gui_data, &item),
ToolType::SimilarVideos => process_bar_similar_videos(&gui_data, &item),
ToolType::TemporaryFiles => process_bar_temporary(&gui_data, &item),
ToolType::InvalidSymlinks => process_bar_invalid_symlinks(&gui_data, &item),
ToolType::BrokenFiles => process_bar_broken_files(&gui_data, &item),
ToolType::BadExtensions => process_bar_bad_extensions(&gui_data, &item),
ToolType::None => panic!(),
loop {
let item = progress_receiver.try_recv();
if let Ok(item) = item {
match item.tool_type {
ToolType::Duplicate => process_bar_duplicates(&gui_data, &item),
ToolType::EmptyFiles => process_bar_empty_files(&gui_data, &item),
ToolType::EmptyFolders => process_bar_empty_folder(&gui_data, &item),
ToolType::BigFile => process_bar_big_files(&gui_data, &item),
ToolType::SameMusic => process_bar_same_music(&gui_data, &item),
ToolType::SimilarImages => process_bar_similar_images(&gui_data, &item),
ToolType::SimilarVideos => process_bar_similar_videos(&gui_data, &item),
ToolType::TemporaryFiles => process_bar_temporary(&gui_data, &item),
ToolType::InvalidSymlinks => process_bar_invalid_symlinks(&gui_data, &item),
ToolType::BrokenFiles => process_bar_broken_files(&gui_data, &item),
ToolType::BadExtensions => process_bar_bad_extensions(&gui_data, &item),
ToolType::None => panic!(),
}
}
glib::timeout_future(Duration::from_millis(300)).await;
}
};
main_context.spawn_local(future);
}

View file

@ -5,11 +5,10 @@
#![allow(clippy::type_complexity)]
#![allow(clippy::needless_late_init)]
use crossbeam_channel::{unbounded, Receiver, Sender};
use std::env;
use std::ffi::OsString;
use futures::channel::mpsc;
use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender};
use glib::Priority;
use gtk4::gio::ApplicationFlags;
use gtk4::prelude::*;
@ -87,7 +86,7 @@ fn build_ui(application: &Application, arguments: &[OsString]) {
let (glib_stop_sender, glib_stop_receiver) = glib::MainContext::channel(Priority::default());
// Futures progress report
let (progress_sender, progress_receiver): (UnboundedSender<ProgressData>, UnboundedReceiver<ProgressData>) = mpsc::unbounded();
let (progress_sender, progress_receiver): (Sender<ProgressData>, Receiver<ProgressData>) = unbounded();
initialize_gui(&gui_data);
validate_notebook_data(&gui_data); // Must be run after initialization of gui, to check if everything was properly setup

View file

@ -1,4 +1,5 @@
use crate::{MainWindow, ProgressToSend};
use crossbeam_channel::Receiver;
use czkawka_core::common_dir_traversal::ProgressData;
use slint::{ComponentHandle, SharedString};

View file

@ -12,6 +12,7 @@ use std::thread;
pub fn connect_scan_button(app: &MainWindow, progress_sender: Sender<ProgressData>) {
let a = app.as_weak();
app.on_scanned(move |active_tab| {
let progress_sender = progress_sender.clone();
let app = a.upgrade().unwrap();
app.set_scanning(true);
app.set_progress_datas(ProgressToSend {
@ -23,18 +24,18 @@ pub fn connect_scan_button(app: &MainWindow, progress_sender: Sender<ProgressDat
let a = app.as_weak();
match active_tab {
CurrentTab::EmptyFolders => {
scan_empty_folders(a, &progress_sender);
scan_empty_folders(a, progress_sender);
}
_ => panic!(),
}
});
}
fn scan_empty_folders(a: Weak<MainWindow>, progress_sender: &Sender<ProgressData>) {
fn scan_empty_folders(a: Weak<MainWindow>, progress_sender: Sender<ProgressData>) {
thread::spawn(move || {
let mut ef = EmptyFolder::new();
ef.set_included_directory(vec![PathBuf::from("/home/rafal/Desktop")]);
ef.find_empty_folders(None, Some(progress_sender));
ef.find_empty_folders(None, Some(&progress_sender));
ef.get_empty_folder_list();