Fixed inaccurate ETAs: use current average rate over last 30 seconds instead of global rate
using global rate gives wildly inacurrate ETAs if rate changes over time.
this makes pv keep a history of progress over the last 30s interval and compute
current average rate over that, which fixes the issue.
fixed -a, --average-rate: show current average rate instead of global rate
[ quick test ]
- in one shell:
$ dd if=/dev/zero of=/tmp/foo bs=1M count=5 # simulate fast initial rate,
$ (while true; do ls /*; sleep 1; done) >> /tmp/foo # then slow rate. leave running ...
- in another shell:
$ tail -f -n +1 /tmp/foo | pv -s 800M > /dev/null
5.62MiB 0:00:17 [33.1KiB/s] [> ] 0% ETA 0:40:02
bad: (pv 1.6.6 - 1.6.20)
ETA of a few minutes that keeps increasing ever and ever ...
5.62MiB 0:00:16 [33.1KiB/s] [> ] 0% ETA 6:45:53
good:
ETA of 6+ hours, which is how long it'll take to reach 800Mb at 33k/s
This commit is contained in:
@@ -45,6 +45,12 @@ extern "C" {
|
||||
#define MAXIMISE_BUFFER_FILL 1
|
||||
|
||||
|
||||
typedef struct pvhistory {
|
||||
long long total_bytes;
|
||||
long double elapsed_sec;
|
||||
} pvhistory_t;
|
||||
|
||||
|
||||
/*
|
||||
* Structure for holding PV internal state. Opaque outside the PV library.
|
||||
*/
|
||||
@@ -113,6 +119,15 @@ struct pvstate_s {
|
||||
long double prev_elapsed_sec;
|
||||
long double prev_rate;
|
||||
long double prev_trans;
|
||||
|
||||
/* Keep track of progress over last intervals to compute current average rate. */
|
||||
pvhistory_t *history; /* state at previous intervals (circular buffer) */
|
||||
int history_len; /* total size */
|
||||
int history_interval; /* seconds between each history entry */
|
||||
int history_first;
|
||||
int history_last;
|
||||
long double current_avg_rate; /* current average rate over last history intervals */
|
||||
|
||||
unsigned long long initial_offset;
|
||||
char *display_buffer;
|
||||
long display_buffer_size;
|
||||
|
||||
Reference in New Issue
Block a user