Skip to content

Commit

Permalink
make display of total transferred more accurate
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
Nicolas Pitre authored and gitster committed Nov 5, 2007
1 parent 0d8aafd commit 218558a
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 28 deletions.
4 changes: 3 additions & 1 deletion csum-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ static void sha1flush(struct sha1file *f, unsigned int count)
for (;;) {
int ret = xwrite(f->fd, buf, count);
if (ret > 0) {
display_throughput(f->tp, ret);
f->total += ret;
display_throughput(f->tp, f->total);
buf = (char *) buf + ret;
count -= ret;
if (count)
Expand Down Expand Up @@ -101,6 +102,7 @@ struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp
f->fd = fd;
f->error = 0;
f->offset = 0;
f->total = 0;
f->tp = tp;
f->do_crc = 0;
SHA1_Init(&f->ctx);
Expand Down
1 change: 1 addition & 0 deletions csum-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ struct sha1file {
int fd, error;
unsigned int offset, namelen;
SHA_CTX ctx;
off_t total;
struct progress *tp;
char name[PATH_MAX];
int do_crc;
Expand Down
4 changes: 2 additions & 2 deletions index-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ static void *fill(int min)
die("early EOF");
die("read error on input: %s", strerror(errno));
}
if (from_stdin)
display_throughput(progress, ret);
input_len += ret;
if (from_stdin)
display_throughput(progress, consumed_bytes + input_len);
} while (input_len < min);
return input_buffer;
}
Expand Down
46 changes: 22 additions & 24 deletions progress.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@
#define TP_IDX_MAX 8

struct throughput {
off_t prev_total;
struct timeval prev_tv;
off_t total;
unsigned long count;
unsigned long avg_bytes;
unsigned long last_bytes[TP_IDX_MAX];
unsigned int avg_bytes;
unsigned int last_bytes[TP_IDX_MAX];
unsigned int avg_misecs;
unsigned int last_misecs[TP_IDX_MAX];
unsigned int idx;
Expand Down Expand Up @@ -110,7 +109,7 @@ static int display(struct progress *progress, unsigned n, int done)
return 0;
}

void display_throughput(struct progress *progress, unsigned long n)
void display_throughput(struct progress *progress, off_t total)
{
struct throughput *tp;
struct timeval tv;
Expand All @@ -124,14 +123,13 @@ void display_throughput(struct progress *progress, unsigned long n)

if (!tp) {
progress->throughput = tp = calloc(1, sizeof(*tp));
if (tp)
if (tp) {
tp->prev_total = total;
tp->prev_tv = tv;
}
return;
}

tp->total += n;
tp->count += n;

/*
* We have x = bytes and y = microsecs. We want z = KiB/s:
*
Expand All @@ -152,37 +150,37 @@ void display_throughput(struct progress *progress, unsigned long n)

if (misecs > 512) {
int l = sizeof(tp->display);
unsigned int count = total - tp->prev_total;
tp->prev_total = total;
tp->prev_tv = tv;
tp->avg_bytes += tp->count;
tp->avg_bytes += count;
tp->avg_misecs += misecs;

if (tp->total > 1 << 30) {
if (total > 1 << 30) {
l -= snprintf(tp->display, l, ", %u.%2.2u GiB",
(int)(tp->total >> 30),
(int)(tp->total & ((1 << 30) - 1)) / 10737419);
} else if (tp->total > 1 << 20) {
(int)(total >> 30),
(int)(total & ((1 << 30) - 1)) / 10737419);
} else if (total > 1 << 20) {
l -= snprintf(tp->display, l, ", %u.%2.2u MiB",
(int)(tp->total >> 20),
((int)(tp->total & ((1 << 20) - 1))
(int)(total >> 20),
((int)(total & ((1 << 20) - 1))
* 100) >> 20);
} else if (tp->total > 1 << 10) {
} else if (total > 1 << 10) {
l -= snprintf(tp->display, l, ", %u.%2.2u KiB",
(int)(tp->total >> 10),
((int)(tp->total & ((1 << 10) - 1))
(int)(total >> 10),
((int)(total & ((1 << 10) - 1))
* 100) >> 10);
} else {
l -= snprintf(tp->display, l, ", %u bytes",
(int)tp->total);
l -= snprintf(tp->display, l, ", %u bytes", (int)total);
}
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_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->idx = (tp->idx + 1) % TP_IDX_MAX;
tp->count = 0;

if (progress->last_value != -1 && progress_update)
display(progress, progress->last_value, 0);
Expand Down
2 changes: 1 addition & 1 deletion progress.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

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);
struct progress *start_progress(const char *title, unsigned total);
struct progress *start_progress_delay(const char *title, unsigned total,
Expand Down

0 comments on commit 218558a

Please sign in to comment.