make display of total transferred more accurate
The throughput display needs a delay period before accounting and displaying anything. Yet it might be called after some amount of data has already been transferred. The display of total data is therefore accounted late and therefore smaller than the reality. Let's call display_throughput() with an absolute amount of transferred data instead of a relative number, and let the throughput code find the relative amount of data by itself as needed. This way the displayed total is always exact. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
0d8aafd252
commit
218558af59
@ -18,7 +18,8 @@ static void sha1flush(struct sha1file *f, unsigned int count)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
int ret = xwrite(f->fd, buf, count);
|
int ret = xwrite(f->fd, buf, count);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
display_throughput(f->tp, ret);
|
f->total += ret;
|
||||||
|
display_throughput(f->tp, f->total);
|
||||||
buf = (char *) buf + ret;
|
buf = (char *) buf + ret;
|
||||||
count -= ret;
|
count -= ret;
|
||||||
if (count)
|
if (count)
|
||||||
@ -101,6 +102,7 @@ struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp
|
|||||||
f->fd = fd;
|
f->fd = fd;
|
||||||
f->error = 0;
|
f->error = 0;
|
||||||
f->offset = 0;
|
f->offset = 0;
|
||||||
|
f->total = 0;
|
||||||
f->tp = tp;
|
f->tp = tp;
|
||||||
f->do_crc = 0;
|
f->do_crc = 0;
|
||||||
SHA1_Init(&f->ctx);
|
SHA1_Init(&f->ctx);
|
||||||
|
@ -8,6 +8,7 @@ struct sha1file {
|
|||||||
int fd, error;
|
int fd, error;
|
||||||
unsigned int offset, namelen;
|
unsigned int offset, namelen;
|
||||||
SHA_CTX ctx;
|
SHA_CTX ctx;
|
||||||
|
off_t total;
|
||||||
struct progress *tp;
|
struct progress *tp;
|
||||||
char name[PATH_MAX];
|
char name[PATH_MAX];
|
||||||
int do_crc;
|
int do_crc;
|
||||||
|
@ -87,9 +87,9 @@ static void *fill(int min)
|
|||||||
die("early EOF");
|
die("early EOF");
|
||||||
die("read error on input: %s", strerror(errno));
|
die("read error on input: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
if (from_stdin)
|
|
||||||
display_throughput(progress, ret);
|
|
||||||
input_len += ret;
|
input_len += ret;
|
||||||
|
if (from_stdin)
|
||||||
|
display_throughput(progress, consumed_bytes + input_len);
|
||||||
} while (input_len < min);
|
} while (input_len < min);
|
||||||
return input_buffer;
|
return input_buffer;
|
||||||
}
|
}
|
||||||
|
46
progress.c
46
progress.c
@ -14,11 +14,10 @@
|
|||||||
#define TP_IDX_MAX 8
|
#define TP_IDX_MAX 8
|
||||||
|
|
||||||
struct throughput {
|
struct throughput {
|
||||||
|
off_t prev_total;
|
||||||
struct timeval prev_tv;
|
struct timeval prev_tv;
|
||||||
off_t total;
|
unsigned int avg_bytes;
|
||||||
unsigned long count;
|
unsigned int last_bytes[TP_IDX_MAX];
|
||||||
unsigned long avg_bytes;
|
|
||||||
unsigned long last_bytes[TP_IDX_MAX];
|
|
||||||
unsigned int avg_misecs;
|
unsigned int avg_misecs;
|
||||||
unsigned int last_misecs[TP_IDX_MAX];
|
unsigned int last_misecs[TP_IDX_MAX];
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
@ -110,7 +109,7 @@ static int display(struct progress *progress, unsigned n, int done)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_throughput(struct progress *progress, unsigned long n)
|
void display_throughput(struct progress *progress, off_t total)
|
||||||
{
|
{
|
||||||
struct throughput *tp;
|
struct throughput *tp;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
@ -124,14 +123,13 @@ void display_throughput(struct progress *progress, unsigned long n)
|
|||||||
|
|
||||||
if (!tp) {
|
if (!tp) {
|
||||||
progress->throughput = tp = calloc(1, sizeof(*tp));
|
progress->throughput = tp = calloc(1, sizeof(*tp));
|
||||||
if (tp)
|
if (tp) {
|
||||||
|
tp->prev_total = total;
|
||||||
tp->prev_tv = tv;
|
tp->prev_tv = tv;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tp->total += n;
|
|
||||||
tp->count += n;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have x = bytes and y = microsecs. We want z = KiB/s:
|
* We have x = bytes and y = microsecs. We want z = KiB/s:
|
||||||
*
|
*
|
||||||
@ -152,37 +150,37 @@ void display_throughput(struct progress *progress, unsigned long n)
|
|||||||
|
|
||||||
if (misecs > 512) {
|
if (misecs > 512) {
|
||||||
int l = sizeof(tp->display);
|
int l = sizeof(tp->display);
|
||||||
|
unsigned int count = total - tp->prev_total;
|
||||||
|
tp->prev_total = total;
|
||||||
tp->prev_tv = tv;
|
tp->prev_tv = tv;
|
||||||
tp->avg_bytes += tp->count;
|
tp->avg_bytes += count;
|
||||||
tp->avg_misecs += misecs;
|
tp->avg_misecs += misecs;
|
||||||
|
|
||||||
if (tp->total > 1 << 30) {
|
if (total > 1 << 30) {
|
||||||
l -= snprintf(tp->display, l, ", %u.%2.2u GiB",
|
l -= snprintf(tp->display, l, ", %u.%2.2u GiB",
|
||||||
(int)(tp->total >> 30),
|
(int)(total >> 30),
|
||||||
(int)(tp->total & ((1 << 30) - 1)) / 10737419);
|
(int)(total & ((1 << 30) - 1)) / 10737419);
|
||||||
} else if (tp->total > 1 << 20) {
|
} else if (total > 1 << 20) {
|
||||||
l -= snprintf(tp->display, l, ", %u.%2.2u MiB",
|
l -= snprintf(tp->display, l, ", %u.%2.2u MiB",
|
||||||
(int)(tp->total >> 20),
|
(int)(total >> 20),
|
||||||
((int)(tp->total & ((1 << 20) - 1))
|
((int)(total & ((1 << 20) - 1))
|
||||||
* 100) >> 20);
|
* 100) >> 20);
|
||||||
} else if (tp->total > 1 << 10) {
|
} else if (total > 1 << 10) {
|
||||||
l -= snprintf(tp->display, l, ", %u.%2.2u KiB",
|
l -= snprintf(tp->display, l, ", %u.%2.2u KiB",
|
||||||
(int)(tp->total >> 10),
|
(int)(total >> 10),
|
||||||
((int)(tp->total & ((1 << 10) - 1))
|
((int)(total & ((1 << 10) - 1))
|
||||||
* 100) >> 10);
|
* 100) >> 10);
|
||||||
} else {
|
} else {
|
||||||
l -= snprintf(tp->display, l, ", %u bytes",
|
l -= snprintf(tp->display, l, ", %u bytes", (int)total);
|
||||||
(int)tp->total);
|
|
||||||
}
|
}
|
||||||
snprintf(tp->display + sizeof(tp->display) - l, l,
|
snprintf(tp->display + sizeof(tp->display) - l, l,
|
||||||
" | %lu KiB/s", tp->avg_bytes / tp->avg_misecs);
|
" | %u KiB/s", tp->avg_bytes / tp->avg_misecs);
|
||||||
|
|
||||||
tp->avg_bytes -= tp->last_bytes[tp->idx];
|
tp->avg_bytes -= tp->last_bytes[tp->idx];
|
||||||
tp->avg_misecs -= tp->last_misecs[tp->idx];
|
tp->avg_misecs -= tp->last_misecs[tp->idx];
|
||||||
tp->last_bytes[tp->idx] = tp->count;
|
tp->last_bytes[tp->idx] = count;
|
||||||
tp->last_misecs[tp->idx] = misecs;
|
tp->last_misecs[tp->idx] = misecs;
|
||||||
tp->idx = (tp->idx + 1) % TP_IDX_MAX;
|
tp->idx = (tp->idx + 1) % TP_IDX_MAX;
|
||||||
tp->count = 0;
|
|
||||||
|
|
||||||
if (progress->last_value != -1 && progress_update)
|
if (progress->last_value != -1 && progress_update)
|
||||||
display(progress, progress->last_value, 0);
|
display(progress, progress->last_value, 0);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
struct progress;
|
struct progress;
|
||||||
|
|
||||||
void display_throughput(struct progress *progress, unsigned long n);
|
void display_throughput(struct progress *progress, off_t total);
|
||||||
int display_progress(struct progress *progress, unsigned n);
|
int display_progress(struct progress *progress, unsigned n);
|
||||||
struct progress *start_progress(const char *title, unsigned total);
|
struct progress *start_progress(const char *title, unsigned total);
|
||||||
struct progress *start_progress_delay(const char *title, unsigned total,
|
struct progress *start_progress_delay(const char *title, unsigned total,
|
||||||
|
Loading…
Reference in New Issue
Block a user