Way better performance, better multithreading
This commit is contained in:
77
src/main.rs
77
src/main.rs
@@ -2,10 +2,12 @@ use anyhow::{bail, Result};
|
|||||||
use argon2::Config;
|
use argon2::Config;
|
||||||
use chacha20::cipher::{KeyIvInit, StreamCipher};
|
use chacha20::cipher::{KeyIvInit, StreamCipher};
|
||||||
use chacha20::XChaCha20;
|
use chacha20::XChaCha20;
|
||||||
|
use core::time;
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
use rand_core::OsRng;
|
use rand_core::OsRng;
|
||||||
use std::fs::ReadDir;
|
use std::hint;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::{
|
use std::{
|
||||||
env,
|
env,
|
||||||
fs,
|
fs,
|
||||||
@@ -22,7 +24,7 @@ extern crate rpassword;
|
|||||||
|
|
||||||
use rpassword::read_password;
|
use rpassword::read_password;
|
||||||
|
|
||||||
const BUFFER_LEN: usize = 50 * 1024 * 1024; // 50 MiB
|
const BUFFER_LEN: usize = 64 * 1024; // 64 KiB
|
||||||
|
|
||||||
pub fn encrypt_file(
|
pub fn encrypt_file(
|
||||||
source_path: String,
|
source_path: String,
|
||||||
@@ -42,8 +44,7 @@ pub fn encrypt_file(
|
|||||||
|
|
||||||
let mut source_file = File::open(&source_path)?;
|
let mut source_file = File::open(&source_path)?;
|
||||||
let mut dest_file = File::create(dest_path)?;
|
let mut dest_file = File::create(dest_path)?;
|
||||||
|
let mut buffer = vec![0u8; BUFFER_LEN]/* .into_boxed_slice() */;
|
||||||
let mut buffer = vec![0u8; BUFFER_LEN].into_boxed_slice();
|
|
||||||
|
|
||||||
println!("Now encrypting {source_path}");
|
println!("Now encrypting {source_path}");
|
||||||
|
|
||||||
@@ -91,7 +92,6 @@ pub fn decrypt_file(source_path: &Path, pwd: &String, config: &Config) -> Result
|
|||||||
}
|
}
|
||||||
|
|
||||||
println!("Start decrypting File {source_path:?}");
|
println!("Start decrypting File {source_path:?}");
|
||||||
|
|
||||||
let mut source_file = File::open(&source_path)?;
|
let mut source_file = File::open(&source_path)?;
|
||||||
|
|
||||||
source_file.read(&mut nonce)?;
|
source_file.read(&mut nonce)?;
|
||||||
@@ -122,15 +122,14 @@ pub fn decrypt_file(source_path: &Path, pwd: &String, config: &Config) -> Result
|
|||||||
if cfg!(unix) {
|
if cfg!(unix) {
|
||||||
file_name = file_name.replace("\\", "/");
|
file_name = file_name.replace("\\", "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = root_dir_path.join(&file_name);
|
let path = root_dir_path.join(&file_name);
|
||||||
|
|
||||||
let prefix = path.parent().expect("No parent Directory");
|
let prefix = path.parent().expect("No parent Directory");
|
||||||
std::fs::create_dir_all(prefix)?;
|
std::fs::create_dir_all(prefix)?;
|
||||||
|
|
||||||
let mut dest_file = File::create(path)?;
|
let mut dest_file = File::create(path)?;
|
||||||
|
let mut buffer = vec![0u8; BUFFER_LEN]/* .into_boxed_slice() */;
|
||||||
let mut buffer = vec![0u8; BUFFER_LEN].into_boxed_slice();
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let read_count = source_file.read(&mut buffer)?;
|
let read_count = source_file.read(&mut buffer)?;
|
||||||
|
|
||||||
@@ -139,6 +138,7 @@ pub fn decrypt_file(source_path: &Path, pwd: &String, config: &Config) -> Result
|
|||||||
dest_file.write(&buffer)?;
|
dest_file.write(&buffer)?;
|
||||||
} else {
|
} else {
|
||||||
cipher.apply_keystream(&mut buffer[..read_count]);
|
cipher.apply_keystream(&mut buffer[..read_count]);
|
||||||
|
|
||||||
dest_file.write(&buffer[..read_count])?;
|
dest_file.write(&buffer[..read_count])?;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -146,6 +146,7 @@ pub fn decrypt_file(source_path: &Path, pwd: &String, config: &Config) -> Result
|
|||||||
|
|
||||||
println!("Finished decrpyting File {file_name}");
|
println!("Finished decrpyting File {file_name}");
|
||||||
|
|
||||||
|
fs::remove_file(source_path)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,40 +201,39 @@ fn main() -> io::Result<()> {
|
|||||||
std::io::stdout().flush().unwrap();
|
std::io::stdout().flush().unwrap();
|
||||||
let pwd = Arc::new(read_password().unwrap());
|
let pwd = Arc::new(read_password().unwrap());
|
||||||
|
|
||||||
let config = Arc::new(config);
|
|
||||||
|
|
||||||
let mut handles: Vec<JoinHandle<()>> = Vec::with_capacity(max_threads);
|
let mut handles: Vec<JoinHandle<()>> = Vec::with_capacity(max_threads);
|
||||||
|
let curr_threads = Arc::new(AtomicUsize::new(0));
|
||||||
let mut current_threads = 0;
|
|
||||||
|
|
||||||
for path_result in paths {
|
for path_result in paths {
|
||||||
let path = path_result.unwrap().path();
|
let path = path_result.unwrap().path();
|
||||||
let pwd = pwd.clone();
|
let pwd = pwd.clone();
|
||||||
let config = config.clone();
|
let config = config.clone();
|
||||||
|
let curr_threads_clone = curr_threads.clone();
|
||||||
|
|
||||||
handles.push(thread::spawn(move || {
|
handles.push(thread::spawn(move || {
|
||||||
|
curr_threads_clone.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
decrypt_file(path.as_path(), &pwd, &config).unwrap();
|
decrypt_file(
|
||||||
fs::remove_file(String::from(path.to_str().unwrap())).unwrap();
|
path.as_path(),
|
||||||
|
&pwd,
|
||||||
|
&config
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curr_threads_clone.fetch_sub(1, std::sync::atomic::Ordering::SeqCst);
|
||||||
}));
|
}));
|
||||||
current_threads += 1;
|
|
||||||
|
|
||||||
if current_threads >= max_threads {
|
while curr_threads.load(std::sync::atomic::Ordering::SeqCst) >= max_threads {
|
||||||
while let Some(handle) = handles.pop() {
|
hint::spin_loop();
|
||||||
handle.join().unwrap();
|
|
||||||
current_threads -= 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if current_threads > 0 {
|
for thread in handles {
|
||||||
while let Some(handle) = handles.pop() {
|
let _ = thread.join();
|
||||||
handle.join().unwrap();
|
|
||||||
current_threads -= 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread::sleep(time::Duration::from_millis(10));
|
||||||
fs::remove_dir(private)?;
|
fs::remove_dir(private)?;
|
||||||
} else {
|
} else {
|
||||||
let root_dir = fs::read_dir(&cwd).unwrap();
|
let root_dir = fs::read_dir(&cwd).unwrap();
|
||||||
@@ -261,24 +261,21 @@ fn main() -> io::Result<()> {
|
|||||||
print!("Type password to encrypt files: ");
|
print!("Type password to encrypt files: ");
|
||||||
std::io::stdout().flush().unwrap();
|
std::io::stdout().flush().unwrap();
|
||||||
let pwd = Arc::new(read_password().unwrap());
|
let pwd = Arc::new(read_password().unwrap());
|
||||||
|
|
||||||
let mut nonce = [0u8; 24];
|
|
||||||
OsRng.fill_bytes(&mut nonce);
|
|
||||||
|
|
||||||
let exe = Arc::new(exe);
|
let exe = Arc::new(exe);
|
||||||
// let private = Arc::new(private);
|
|
||||||
|
|
||||||
let mut handles: Vec<JoinHandle<()>> = Vec::with_capacity(max_threads);
|
let mut handles: Vec<JoinHandle<()>> = Vec::with_capacity(max_threads);
|
||||||
let mut current_threads = 0;
|
|
||||||
let cwd: Arc<String> = Arc::from(String::from(cwd.to_str().unwrap()));
|
let cwd: Arc<String> = Arc::from(String::from(cwd.to_str().unwrap()));
|
||||||
|
|
||||||
|
let curr_threads = Arc::new(AtomicUsize::new(0));
|
||||||
|
|
||||||
for path in paths {
|
for path in paths {
|
||||||
let pwd = pwd.clone();
|
let pwd = pwd.clone();
|
||||||
let exe = exe.clone();
|
let exe = exe.clone();
|
||||||
let config = config.clone();
|
let config = config.clone();
|
||||||
let cwd = cwd.clone();
|
let cwd = cwd.clone();
|
||||||
|
let curr_threads_clone = curr_threads.clone();
|
||||||
|
|
||||||
handles.push(thread::spawn(move || {
|
handles.push(thread::spawn(move || {
|
||||||
|
curr_threads_clone.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
||||||
if path.is_file() && path.as_os_str() != exe.as_os_str() {
|
if path.is_file() && path.as_os_str() != exe.as_os_str() {
|
||||||
encrypt_file(
|
encrypt_file(
|
||||||
String::from(path.to_str().unwrap()),
|
String::from(path.to_str().unwrap()),
|
||||||
@@ -288,22 +285,16 @@ fn main() -> io::Result<()> {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
curr_threads_clone.fetch_sub(1, std::sync::atomic::Ordering::SeqCst);
|
||||||
}));
|
}));
|
||||||
current_threads += 1;
|
|
||||||
|
|
||||||
if current_threads >= max_threads {
|
while curr_threads.load(std::sync::atomic::Ordering::SeqCst) >= max_threads {
|
||||||
while let Some(handle) = handles.pop() {
|
hint::spin_loop();
|
||||||
handle.join().unwrap();
|
|
||||||
current_threads -= 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if current_threads > 0 {
|
for thread in handles {
|
||||||
while let Some(handle) = handles.pop() {
|
let _ = thread.join();
|
||||||
handle.join().unwrap();
|
|
||||||
current_threads -= 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for dir in dir_list {
|
for dir in dir_list {
|
||||||
|
|||||||
Reference in New Issue
Block a user