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:
andy.boot
2023-01-14 18:09:45 +00:00
parent 414bc9e5a7
commit 3708edc2d3
2 changed files with 26 additions and 63 deletions

View File

@@ -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(

View File

@@ -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();
}