diff options
author | Sebastian Thiel <sebastian.thiel@icloud.com> | 2023-05-02 10:55:47 +0200 |
---|---|---|
committer | Sebastian Thiel <sebastian.thiel@icloud.com> | 2023-05-05 12:28:10 +0200 |
commit | c921dc72d3008179e72df9d85f0e0c21c998e199 (patch) | |
tree | 55ae29f3639ba73f891143374ec83d66020b6b01 | |
parent | e03c560e8b54e2e231d578e1d5e9dcd206d34216 (diff) |
Simplify GUI refreshes by using a throttle
-rw-r--r-- | src/aggregate.rs | 2 | ||||
-rw-r--r-- | src/common.rs | 13 | ||||
-rw-r--r-- | src/traverse.rs | 29 |
3 files changed, 16 insertions, 28 deletions
diff --git a/src/aggregate.rs b/src/aggregate.rs index e897dbd..895282f 100644 --- a/src/aggregate.rs +++ b/src/aggregate.rs @@ -25,7 +25,7 @@ pub fn aggregate( let mut num_roots = 0; let mut aggregates = Vec::new(); let mut inodes = InodeFilter::default(); - let progress = Throttle::new(Duration::from_millis(100)); + let progress = Throttle::new(Duration::from_millis(100), Duration::from_secs(1).into()); for path in paths.into_iter() { num_roots += 1; diff --git a/src/common.rs b/src/common.rs index a277c1f..ab71426 100644 --- a/src/common.rs +++ b/src/common.rs @@ -124,14 +124,16 @@ pub struct Throttle { } impl Throttle { - pub fn new(duration: Duration) -> Self { + pub fn new(duration: Duration, initial_sleep: Option<Duration>) -> Self { let instance = Self { trigger: Default::default(), }; let trigger = Arc::downgrade(&instance.trigger); std::thread::spawn(move || { - std::thread::sleep(Duration::from_secs(1)); + if let Some(duration) = initial_sleep { + std::thread::sleep(duration) + } while let Some(t) = trigger.upgrade() { t.store(true, Ordering::Relaxed); std::thread::sleep(duration); @@ -145,10 +147,15 @@ impl Throttle { where F: FnOnce(), { - if self.trigger.swap(false, Ordering::Relaxed) { + if self.can_update() { f() } } + + /// Return `true` if we are not currently throttled. + pub fn can_update(&self) -> bool { + self.trigger.swap(false, Ordering::Relaxed) + } } /// Configures a filesystem walk, including output and formatting options. diff --git a/src/traverse.rs b/src/traverse.rs index f61ab41..80305eb 100644 --- a/src/traverse.rs +++ b/src/traverse.rs @@ -1,4 +1,4 @@ -use crate::{crossdev, get_size_or_panic, InodeFilter, WalkOptions}; +use crate::{crossdev, get_size_or_panic, InodeFilter, Throttle, WalkOptions}; use anyhow::Result; use filesize::PathExt; use petgraph::{graph::NodeIndex, stable_graph::StableGraph, Directed, Direction}; @@ -6,7 +6,7 @@ use std::{ fs::Metadata, io, path::{Path, PathBuf}, - time::{Duration, Instant}, + time::Duration, }; pub type TreeIndex = NodeIndex; @@ -21,8 +21,6 @@ pub struct EntryData { pub metadata_io_error: bool, } -const REFRESH_RATE: Duration = Duration::from_millis(100); - /// The result of the previous filesystem traversal #[derive(Default, Debug)] pub struct Traversal { @@ -74,10 +72,7 @@ impl Traversal { let mut previous_depth = 0; let mut inodes = InodeFilter::default(); - let mut last_checked = Instant::now(); - - const INITIAL_CHECK_INTERVAL: usize = 500; - let mut check_instant_every = INITIAL_CHECK_INTERVAL; + let throttle = Throttle::new(Duration::from_millis(250), None); if walk_options.threads == 0 { // avoid using the global rayon pool, as it will keep a lot of threads alive after we are done. // Also means that we will spin up a bunch of threads per root path, instead of reusing them. @@ -94,7 +89,6 @@ impl Traversal { } for path in input.into_iter() { - let mut last_seen_eid = 0; let device_id = match crossdev::init(path.as_ref()) { Ok(id) => id, Err(_) => { @@ -102,10 +96,9 @@ impl Traversal { continue; } }; - for (eid, entry) in walk_options + for entry in walk_options .iter_from_path(path.as_ref(), device_id) .into_iter() - .enumerate() { t.entries_traversed += 1; let mut data = EntryData::default(); @@ -191,19 +184,7 @@ impl Traversal { } } - if eid != 0 - && eid % check_instant_every == 0 - && last_checked.elapsed() >= REFRESH_RATE - { - let now = Instant::now(); - let elapsed = (now - last_checked).as_millis() as f64; - check_instant_every = (INITIAL_CHECK_INTERVAL as f64 - * ((eid - last_seen_eid) as f64 / INITIAL_CHECK_INTERVAL as f64) - * (REFRESH_RATE.as_millis() as f64 / elapsed)) - .max(1.0) as usize; - last_seen_eid = eid; - last_checked = now; - + if throttle.can_update() { if update(&mut t)? { return Ok(None); } |