Skip to content

Commit

Permalink
Time progress (#151)
Browse files Browse the repository at this point in the history
* io

* set_progress

* set_progress

* ", "

* set_progress

* elapsed

* time left:

* fmt

* time

* h,m,s

* hms

* 02

* update once a second

* clones

* no update

* millis?

* f64

* -1.0

* 2

* ok

* println

* x

* x

* 0.1

* a

* elapsed

* ?

* ?

* 24 frames (0.04 s)

* millis

* 0.8.1

* left

* no dot at the end

* 0.01

* comment

* 0.01 s

* 0.02

* 0.04

* 0.02

* 0.01

* better

* cover 2
  • Loading branch information
sergey-shandar authored Nov 14, 2023
1 parent 84d9544 commit 1e251da
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 49 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ members = ["blockset", "blockset-lib"]
resolver = "2"

[workspace.package]
version = "0.4.0"
version = "0.4.1"
edition = "2021"
license = "GPL-3.0-or-later"
authors = ["Sergey Shandar"]
repository = "https://github.com/datablockset/blockset"

[workspace.dependencies]
io-trait = "0.6.0"
io-impl = "0.6.0"
io-test = "0.6.0"
io-trait = "0.8.0"
io-impl = "0.8.0"
io-test = "0.8.1"
wasm-bindgen-test = "0.3.38"
25 changes: 13 additions & 12 deletions blockset-lib/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,36 @@ use crate::{
forest::{file::FileForest, node_id::ForestNodeId, tree_add::ForestTreeAdd, Forest},
info::calculate_total,
progress::{self, Progress},
state::{mb, progress, State},
state::{mb, State},
uint::u224::U224,
};

fn read_to_tree<T: TreeAdd>(
s: T,
mut file: impl Read + Progress,
stdout: &mut impl Write,
io: &impl Io,
display_new: bool,
) -> io::Result<String> {
let mut tree = MainTreeAdd::new(s);
let mut state = State::new(stdout);
let mut state = State::new(io);
let mut new = 0;
loop {
let pr = file.progress();
let progress::State { current, total } = pr?;
let mut buf = [0; 1024];
let p = if total == 0 {
100
1.0
} else {
current * 100 / total
(current as f64) / (total as f64)
};
let s = if display_new {
"New data: ".to_owned() + &mb(new) + ". "
} else {
String::new()
} + "Processed: "
+ &progress(current, p as u8);
state.set(&s)?;
+ &mb(current)
+ ", ";
state.set_progress(&s, p)?;
let size = file.read(buf.as_mut())?;
if size == 0 {
break;
Expand Down Expand Up @@ -85,9 +86,9 @@ fn add<'a, T: Io, S: 'a + TreeAdd>(
// this may lead to incorrect progress bar because, a size of a file with replaced CRLF
// is smaller than `len`. Proposed solution:
// a Read implementation which can also report a progress.
read_to_tree(s, ToPosixEol::new(f), stdout, display_new)?
read_to_tree(s, ToPosixEol::new(f), io, display_new)?
} else {
read_to_tree(s, f, stdout, display_new)?
read_to_tree(s, f, io, display_new)?
};
println(stdout, &k)?;
Ok(())
Expand Down Expand Up @@ -118,7 +119,7 @@ pub fn run(io: &impl Io) -> io::Result<()> {
let path = a.next().ok_or(invalid_input("missing file name"))?;
let mut f = io.create(&path)?;
let table = FileForest(io);
table.restore(&ForestNodeId::new(NodeType::Root, &d), &mut f, stdout)?;
table.restore(&ForestNodeId::new(NodeType::Root, &d), &mut f, io)?;
Ok(())
}
"info" => {
Expand Down Expand Up @@ -206,7 +207,7 @@ mod test {
0x68000000_00000000_00000000_00000000,
];
let s = root(&d).to_base32();
assert_eq!(io.stdout.to_stdout(), s.clone() + "\n");
assert_eq!(io.stdout.to_stdout()[..s.len()], s);
let v = io
.read(&("cdt0/roots/".to_owned() + &s[..2] + "/" + &s[2..4] + "/" + &s[4..]))
.unwrap();
Expand Down Expand Up @@ -262,7 +263,7 @@ mod test {
assert!(e.is_ok());
let d: U256 = [0, 0];
let s = root(&d).to_base32();
assert_eq!(io.stdout.to_stdout(), s.clone() + "\n");
assert_eq!(io.stdout.to_stdout()[..s.len()], s);
}

#[wasm_bindgen_test]
Expand Down
17 changes: 7 additions & 10 deletions blockset-lib/src/forest/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::io::{self, Write};

use io_trait::Io;

use crate::{
cdt::{node_id::root, node_type::NodeType},
state::{progress, State},
state::{mb, State},
uint::{u224::U224, u32::from_u8x4},
};

Expand Down Expand Up @@ -31,22 +33,17 @@ pub trait Forest {
Ok(true)
}
// we should extract a state machine from the function and remove `set_progress`.
fn restore(
&self,
id: &ForestNodeId,
w: &mut impl Write,
stdout: &mut impl Write,
) -> io::Result<()> {
fn restore(&self, id: &ForestNodeId, w: &mut impl Write, io: &impl Io) -> io::Result<()> {
if id.hash == EMPTY {
return Ok(());
}
let mut tail = Vec::default();
let mut keys = [(id.hash, 1.0)].to_vec();
let mut progress_p = 0.0;
let mut progress_b = 0;
let mut state = State::new(stdout);
let mut state = State::new(io);
let mut t = id.node_type;
state.set(&progress(0, 0))?;
state.set_progress("", 0.0)?;
while let Some((key, size)) = keys.pop() {
let v = self.get_block(&ForestNodeId::new(t, &key))?;
let mut len = *v.first().unwrap() as usize;
Expand All @@ -55,7 +52,7 @@ pub trait Forest {
w.write_all(buf)?;
progress_p += size;
progress_b += buf.len() as u64;
state.set(&progress(progress_b, (progress_p * 100.0) as u8))?;
state.set_progress(&(mb(progress_b) + ", "), progress_p)?;
} else {
len += 1;
if len > 1 {
Expand Down
8 changes: 3 additions & 5 deletions blockset-lib/src/forest/tree_add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ impl<T: Forest> TreeAdd for ForestTreeAdd<T> {
mod test {
use std::io::Cursor;

use io_test::VirtualIo;
use wasm_bindgen_test::wasm_bindgen_test;

use crate::{
Expand Down Expand Up @@ -169,12 +170,9 @@ mod test {
let k = add(table, c);
let mut v = Vec::default();
let mut cursor = Cursor::new(&mut v);
let io = VirtualIo::new(&[]);
table
.restore(
&ForestNodeId::new(NodeType::Root, &k),
&mut cursor,
&mut Cursor::<Vec<_>>::default(),
)
.restore(&ForestNodeId::new(NodeType::Root, &k), &mut cursor, &io)
.unwrap();
assert_eq!(v, c.as_bytes());
}
Expand Down
11 changes: 3 additions & 8 deletions blockset-lib/src/info/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,8 @@ fn create_map(io: &impl Io, path: &str, is_dir: bool, e: NodeTypeSet) -> DirEntr
}

pub fn calculate_total(io: &impl Io) -> io::Result<u64> {
let stdout = &mut io.stdout();
let mut total = 0;
let state = &mut State::new(stdout);
let state = &mut State::new(io);
let a = create_map(io, "", true, NodeTypeSet::ALL);
let an = a.len() as u64;
for (ai, (af, &e)) in a.iter().enumerate() {
Expand All @@ -78,12 +77,8 @@ pub fn calculate_total(io: &impl Io) -> io::Result<u64> {
}
let p = (bn * ai as u64 + bi as u64 + 1) as f64 / (an * bn) as f64;
let e = total as f64 / p;
let s = "size: ~".to_string()
+ &mb(e as u64)
+ ". "
+ &((p * 100.0) as u64).to_string()
+ "%.";
state.set(&s)?;
let s = "size: ~".to_string() + &mb(e as u64) + ", ";
state.set_progress(&s, p)?;
}
}
Ok(total)
Expand Down
45 changes: 36 additions & 9 deletions blockset-lib/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
use std::io::{self, Write};

pub struct State<'a, T: Write> {
stdout: &'a mut T,
use io_trait::Io;

pub struct State<'a, T: Io> {
io: &'a T,
prior: usize,
start_time: T::Instant,
prior_elapsed: f64,
}

pub fn mb(b: u64) -> String {
(b / 1_000_000).to_string() + " MB"
}

pub fn progress(b: u64, p: u8) -> String {
mb(b) + ", " + &p.to_string() + "%."
fn time(mut t: u64) -> String {
let h = t / 3600;
t %= 3600;
let m = t / 60;
format!("{}:{:02}:{:02}", h, m, t % 60)
}

impl<'a, T: Write> State<'a, T> {
pub fn new(stdout: &'a mut T) -> Self {
Self { stdout, prior: 0 }
impl<'a, T: Io> State<'a, T> {
pub fn new(io: &'a T) -> Self {
Self {
io,
prior: 0,
start_time: io.now(),
prior_elapsed: -1.0,
}
}
pub fn set(&mut self, s: &str) -> io::Result<()> {
let mut vec = Vec::default();
Expand All @@ -26,12 +38,27 @@ impl<'a, T: Write> State<'a, T> {
vec.resize(self.prior * 2, 0x20);
vec.resize(vec.len() + len, 8);
}
self.stdout.write_all(&vec)?;
self.io.stdout().write_all(&vec)?;
self.prior = s.len();
Ok(())
}
pub fn set_progress(&mut self, s: &str, p: f64) -> io::Result<()> {
if p == 0.0 {
return Ok(());
}
let percent = (p * 100.0) as u8;
let current = self.io.now();
let elapsed = (current - self.start_time.clone()).as_secs_f64();
if elapsed - self.prior_elapsed < 0.01 {
return Ok(());
}
self.prior_elapsed = elapsed;
let left = elapsed * (1.0 - p) / p;
let r = s.to_owned() + &percent.to_string() + "%, time left: " + &time(left as u64);
self.set(&r)
}
}
impl<'a, T: Write> Drop for State<'a, T> {
impl<'a, T: Io> Drop for State<'a, T> {
fn drop(&mut self) {
let _ = self.set("");
}
Expand Down
2 changes: 1 addition & 1 deletion blockset/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ repository.workspace = true

[dependencies]
# we should always use a specific version of the blockset-lib
blockset-lib = { path = "../blockset-lib", version = "=0.4.0" }
blockset-lib = { path = "../blockset-lib", version = "=0.4.1" }
io-impl.workspace = true

0 comments on commit 1e251da

Please sign in to comment.