mirror of
https://github.com/bootandy/dust.git
synced 2025-12-12 07:40:40 -08:00
Refactor: Progress bar: Remove atomic classes
On balance I'm not convinced these macro built wrapper classes are worth it - It's clearer to use the standard atomic classes
This commit is contained in:
@@ -2,9 +2,9 @@ use std::fs;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::node::Node;
|
||||
use crate::progress;
|
||||
use crate::progress::ORDERING;
|
||||
use crate::progress::Operation;
|
||||
use crate::progress::PAtomicInfo;
|
||||
use crate::progress::ThreadSyncMathTrait;
|
||||
use crate::progress::ThreadSyncTrait;
|
||||
use crate::utils::is_filtered_out_due_to_invert_regex;
|
||||
use crate::utils::is_filtered_out_due_to_regex;
|
||||
@@ -13,7 +13,6 @@ use rayon::prelude::ParallelIterator;
|
||||
use regex::Regex;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use std::sync::atomic;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
|
||||
use std::collections::HashSet;
|
||||
@@ -43,7 +42,7 @@ pub fn walk_it(dirs: HashSet<PathBuf>, walk_data: WalkData) -> (Vec<Node>, bool)
|
||||
.filter_map(|d| {
|
||||
let node = walk(d, &permissions_flag, &walk_data, 0)?;
|
||||
if let Some(data) = &walk_data.progress_data {
|
||||
data.state.set(progress::Operation::PREPARING);
|
||||
data.state.store(Operation::PREPARING, ORDERING);
|
||||
}
|
||||
clean_inodes(node, &mut inodes, walk_data.use_apparent_size)
|
||||
})
|
||||
@@ -137,13 +136,13 @@ fn walk(
|
||||
let info_data = &walk_data.progress_data;
|
||||
|
||||
if let Some(data) = info_data {
|
||||
data.state.set(progress::Operation::INDEXING);
|
||||
data.state.store(Operation::INDEXING, ORDERING);
|
||||
if depth == 0 {
|
||||
data.current_path.set(dir.to_string_lossy().to_string());
|
||||
|
||||
// reset the value between each target dirs
|
||||
data.total_file_size.set(0);
|
||||
data.file_number.set(0);
|
||||
data.total_file_size.store(0, ORDERING);
|
||||
data.file_number.store(0, ORDERING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,9 +179,9 @@ fn walk(
|
||||
);
|
||||
|
||||
if let Some(data) = info_data {
|
||||
data.file_number.add(1);
|
||||
data.file_number.fetch_add(1, ORDERING);
|
||||
if let Some(ref file) = node {
|
||||
data.total_file_size.add(file.size);
|
||||
data.total_file_size.fetch_add(file.size, ORDERING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +189,7 @@ fn walk(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
permissions_flag.store(true, atomic::Ordering::Relaxed);
|
||||
permissions_flag.store(true, ORDERING);
|
||||
}
|
||||
None
|
||||
})
|
||||
@@ -199,7 +198,7 @@ fn walk(
|
||||
// Handle edge case where dust is called with a file instead of a directory
|
||||
if !dir.exists() {
|
||||
// TODO: Migrate permissions_flag to the new progress_data object
|
||||
permissions_flag.store(true, atomic::Ordering::Relaxed);
|
||||
permissions_flag.store(true, ORDERING);
|
||||
}
|
||||
}
|
||||
build_node(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{
|
||||
io::Write,
|
||||
sync::{
|
||||
atomic::{AtomicBool, AtomicU64, AtomicU8, Ordering},
|
||||
atomic::{AtomicBool, AtomicU64, AtomicU8, AtomicUsize, Ordering},
|
||||
Arc, RwLock,
|
||||
},
|
||||
thread::JoinHandle,
|
||||
@@ -12,54 +12,17 @@ use crate::display::human_readable_number;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
pub const ATOMIC_ORDERING: Ordering = Ordering::Relaxed;
|
||||
pub const ORDERING: Ordering = Ordering::Relaxed;
|
||||
|
||||
const PROGRESS_CHARS_DELTA: u64 = 100;
|
||||
const PROGRESS_CHARS: [char; 4] = ['-', '\\', '|', '/'];
|
||||
const PROGRESS_CHARS_LEN: usize = PROGRESS_CHARS.len();
|
||||
|
||||
// small wrappers for atomic number to reduce overhead
|
||||
pub trait ThreadSyncTrait<T> {
|
||||
fn set(&self, val: T);
|
||||
fn get(&self) -> T;
|
||||
}
|
||||
|
||||
pub trait ThreadSyncMathTrait<T> {
|
||||
fn add(&self, val: T);
|
||||
}
|
||||
|
||||
macro_rules! create_atomic_wrapper {
|
||||
($ident: ident, $atomic_type: ty, $type: ty, $ordering: ident) => {
|
||||
#[derive(Default)]
|
||||
pub struct $ident {
|
||||
inner: $atomic_type,
|
||||
}
|
||||
|
||||
impl ThreadSyncTrait<$type> for $ident {
|
||||
fn set(&self, val: $type) {
|
||||
self.inner.store(val, $ordering)
|
||||
}
|
||||
|
||||
fn get(&self) -> $type {
|
||||
self.inner.load($ordering)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
($ident: ident, $atomic_type: ty, $type: ty, $ordering: ident + add) => {
|
||||
create_atomic_wrapper!($ident, $atomic_type, $type, $ordering);
|
||||
|
||||
impl ThreadSyncMathTrait<$type> for $ident {
|
||||
fn add(&self, val: $type) {
|
||||
self.inner.fetch_add(val, $ordering);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
create_atomic_wrapper!(AtomicU64Wrapper, AtomicU64, u64, ATOMIC_ORDERING + add);
|
||||
create_atomic_wrapper!(AtomicU8Wrapper, AtomicU8, u8, ATOMIC_ORDERING + add);
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ThreadStringWrapper {
|
||||
inner: RwLock<String>,
|
||||
@@ -86,14 +49,12 @@ pub mod Operation {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PAtomicInfo {
|
||||
// pub file_number: AtomicUsize::new(0),
|
||||
pub file_number: AtomicU64Wrapper,
|
||||
pub total_file_size: AtomicU64Wrapper,
|
||||
pub state: AtomicU8Wrapper,
|
||||
pub file_number: AtomicUsize,
|
||||
pub total_file_size: AtomicU64,
|
||||
pub state: AtomicU8,
|
||||
pub current_path: ThreadStringWrapper,
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
fn format_indicator_str(data: &PAtomicInfo, progress_char_i: usize, s: &str) -> String {
|
||||
format!(
|
||||
@@ -115,7 +76,9 @@ impl PIndicator {
|
||||
Self {
|
||||
thread_run: Arc::new(AtomicBool::new(true)),
|
||||
thread: None,
|
||||
data: Arc::new(PAtomicInfo{..Default::default()}),
|
||||
data: Arc::new(PAtomicInfo {
|
||||
..Default::default()
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,16 +91,17 @@ impl PIndicator {
|
||||
let mut stdout = std::io::stdout();
|
||||
std::thread::sleep(Duration::from_millis(PROGRESS_CHARS_DELTA));
|
||||
|
||||
while is_building_data_const.load(ATOMIC_ORDERING) {
|
||||
let msg = match data.state.get() {
|
||||
while is_building_data_const.load(ORDERING) {
|
||||
let msg = match data.state.load(ORDERING) {
|
||||
Operation::INDEXING => {
|
||||
let base = format_indicator_str(&data, progress_char_i, "Indexing");
|
||||
|
||||
let file_count = data.file_number.get();
|
||||
let size = human_readable_number(data.total_file_size.get(), is_iso);
|
||||
let file_count = data.file_number.load(ORDERING);
|
||||
let size = human_readable_number(
|
||||
data.total_file_size.load(ORDERING),
|
||||
is_iso,
|
||||
);
|
||||
let file_str = format!("{} {} files", file_count, size);
|
||||
// let file_str = format!("{} {} files", file_count, data.total_file_size);
|
||||
|
||||
format!("{} - {}", base, file_str)
|
||||
}
|
||||
Operation::PREPARING => {
|
||||
@@ -165,7 +129,7 @@ impl PIndicator {
|
||||
}
|
||||
|
||||
pub fn stop(self) {
|
||||
self.thread_run.store(false, ATOMIC_ORDERING);
|
||||
self.thread_run.store(false, ORDERING);
|
||||
if let Some(t) = self.thread {
|
||||
t.join().unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user