diff --git a/Cargo.lock b/Cargo.lock index e8aa648..50f5692 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,9 +220,9 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" [[package]] name = "js-sys" @@ -236,7 +236,7 @@ dependencies = [ [[package]] name = "l-s" -version = "0.3.3" +version = "0.3.4" dependencies = [ "anyhow", "clap", @@ -295,9 +295,9 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd" [[package]] name = "proc-macro2" @@ -325,9 +325,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea" [[package]] name = "serde" diff --git a/Cargo.toml b/Cargo.toml index 1d064b4..ddf4529 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "l-s" -version = "0.3.3" +version = "0.3.4" authors = ["licsber "] edition = "2021" diff --git a/src/meta/progress.rs b/src/meta/progress.rs index 4699a71..1110c0b 100644 --- a/src/meta/progress.rs +++ b/src/meta/progress.rs @@ -13,6 +13,7 @@ pub struct ProgressTracker { iops: Arc, start_time: Instant, last_update: Arc, + last_bytes: Arc, } impl ProgressTracker { @@ -38,6 +39,7 @@ impl ProgressTracker { iops: Arc::new(AtomicU64::new(0)), start_time: Instant::now(), last_update: Arc::new(AtomicU64::new(0)), + last_bytes: Arc::new(AtomicU64::new(0)), } } @@ -81,10 +83,48 @@ impl ProgressTracker { } /// 获取字节读取回调(可 move) + /// 在读取过程中定期更新消息,提供更高粒度的进度反馈 pub fn bytes_callback(&self) -> impl FnMut(u64) { let bytes_read = self.bytes_read.clone(); + let last_bytes = self.last_bytes.clone(); + let last_update = self.last_update.clone(); + let start_time = self.start_time; + let progress_bar = self.progress_bar.clone(); + let bytes_read_clone = self.bytes_read.clone(); + let iops = self.iops.clone(); + move |bytes| { bytes_read.fetch_add(bytes, Ordering::Relaxed); + + // 每读取 16MB(约4次缓冲区读取)或每 200ms 更新一次消息,提供更细粒度的反馈 + let total_bytes = bytes_read.load(Ordering::Relaxed); + let last_bytes_value = last_bytes.load(Ordering::Relaxed); + let now = start_time.elapsed().as_millis() as u64; + let last_update_value = last_update.load(Ordering::Relaxed); + + // 检查是否需要更新:每 16MB(缓冲区为4MB,约4次读取)或每 200ms + let bytes_diff = total_bytes.saturating_sub(last_bytes_value); + let time_diff = now.saturating_sub(last_update_value); + const UPDATE_BYTES_THRESHOLD: u64 = 16 * 1024 * 1024; // 16MB + const UPDATE_TIME_THRESHOLD: u64 = 200; // 200ms + + if bytes_diff >= UPDATE_BYTES_THRESHOLD || time_diff >= UPDATE_TIME_THRESHOLD { + if let Some(pb) = &progress_bar { + let elapsed = start_time.elapsed().as_secs_f64(); + let total_bytes = bytes_read_clone.load(Ordering::Relaxed); + let total_ops = iops.load(Ordering::Relaxed); + + if total_bytes > 0 && elapsed > 0.0 { + let speed_bytes_per_sec = total_bytes as f64 / elapsed; + let speed_str = friendly_size(speed_bytes_per_sec as u64); + let iops_value = total_ops as f64 / elapsed; + pb.set_message(format!("IO速度: {}/s | IOPS: {:.0}", speed_str, iops_value)); + } + } + + last_bytes.store(total_bytes, Ordering::Relaxed); + last_update.store(now, Ordering::Relaxed); + } } }