summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Thiel <sebastian.thiel@icloud.com>2023-05-02 10:55:47 +0200
committerSebastian Thiel <sebastian.thiel@icloud.com>2023-05-05 12:28:10 +0200
commitc921dc72d3008179e72df9d85f0e0c21c998e199 (patch)
tree55ae29f3639ba73f891143374ec83d66020b6b01
parente03c560e8b54e2e231d578e1d5e9dcd206d34216 (diff)
Simplify GUI refreshes by using a throttle
-rw-r--r--src/aggregate.rs2
-rw-r--r--src/common.rs13
-rw-r--r--src/traverse.rs29
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);
}