{"thread":{"id":"10660","subject":"[PATCH] make display of total transferred more accurate","startedAt":"2007-11-05T03:15:41Z","lastAt":"2007-11-05T03:15:41Z","messageCount":1,"participants":["Nicolas Pitre"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"58342","messageId":"alpine.LFD.0.9999.0711042144290.21255@xanadu.home","threadId":"10660","inReplyTo":null,"subject":"[PATCH] make display of total transferred more accurate","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2007-11-05T03:15:41Z","receivedAt":"2007-11-05T03:15:41Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"The throughput display needs a delay period before accounting and \ndisplaying anything.  Yet it might be called after some amount of data \nhas already been transferred.  The display of total data is therefore \naccounted late and therefore smaller than the reality.\n\nLet's call display_throughput() with an absolute amount of transferred \ndata instead of a relative number, and let the throughput code find the \nrelative amount of data by itself as needed.  This way the displayed \ntotal is always exact.\n\nSigned-off-by: Nicolas Pitre <nico@cam.org>\n---\ndiff --git a/csum-file.c b/csum-file.c\nindex 3729e73..b445e6a 100644\n--- a/csum-file.c\n+++ b/csum-file.c\n@@ -18,7 +18,8 @@ static void sha1flush(struct sha1file *f, unsigned int count)\n \tfor (;;) {\n \t\tint ret = xwrite(f->fd, buf, count);\n \t\tif (ret > 0) {\n-\t\t\tdisplay_throughput(f->tp, ret);\n+\t\t\tf->total += ret;\n+\t\t\tdisplay_throughput(f->tp, f->total);\n \t\t\tbuf = (char *) buf + ret;\n \t\t\tcount -= ret;\n \t\t\tif (count)\n@@ -101,6 +102,7 @@ struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp\n \tf->fd = fd;\n \tf->error = 0;\n \tf->offset = 0;\n+\tf->total = 0;\n \tf->tp = tp;\n \tf->do_crc = 0;\n \tSHA1_Init(&f->ctx);\ndiff --git a/csum-file.h b/csum-file.h\nindex 4d1b231..a38cc3a 100644\n--- a/csum-file.h\n+++ b/csum-file.h\n@@ -8,6 +8,7 @@ struct sha1file {\n \tint fd, error;\n \tunsigned int offset, namelen;\n \tSHA_CTX ctx;\n+\toff_t total;\n \tstruct progress *tp;\n \tchar name[PATH_MAX];\n \tint do_crc;\ndiff --git a/index-pack.c b/index-pack.c\nindex 715a5bb..581a7f5 100644\n--- a/index-pack.c\n+++ b/index-pack.c\n@@ -87,9 +87,9 @@ static void *fill(int min)\n \t\t\t\tdie(\"early EOF\");\n \t\t\tdie(\"read error on input: %s\", strerror(errno));\n \t\t}\n-\t\tif (from_stdin)\n-\t\t\tdisplay_throughput(progress, ret);\n \t\tinput_len += ret;\n+\t\tif (from_stdin)\n+\t\t\tdisplay_throughput(progress, consumed_bytes + input_len);\n \t} while (input_len < min);\n \treturn input_buffer;\n }\ndiff --git a/progress.c b/progress.c\nindex 3f6a602..a963bd8 100644\n--- a/progress.c\n+++ b/progress.c\n@@ -14,11 +14,10 @@\n #define TP_IDX_MAX      8\n \n struct throughput {\n+\toff_t prev_total;\n \tstruct timeval prev_tv;\n-\toff_t total;\n-\tunsigned long count;\n-\tunsigned long avg_bytes;\n-\tunsigned long last_bytes[TP_IDX_MAX];\n+\tunsigned int avg_bytes;\n+\tunsigned int last_bytes[TP_IDX_MAX];\n \tunsigned int avg_misecs;\n \tunsigned int last_misecs[TP_IDX_MAX];\n \tunsigned int idx;\n@@ -110,7 +109,7 @@ static int display(struct progress *progress, unsigned n, int done)\n \treturn 0;\n }\n \n-void display_throughput(struct progress *progress, unsigned long n)\n+void display_throughput(struct progress *progress, off_t total)\n {\n \tstruct throughput *tp;\n \tstruct timeval tv;\n@@ -124,14 +123,13 @@ void display_throughput(struct progress *progress, unsigned long n)\n \n \tif (!tp) {\n \t\tprogress->throughput = tp = calloc(1, sizeof(*tp));\n-\t\tif (tp)\n+\t\tif (tp) {\n+\t\t\ttp->prev_total = total;\n \t\t\ttp->prev_tv = tv;\n+\t\t}\n \t\treturn;\n \t}\n \n-\ttp->total += n;\n-\ttp->count += n;\n-\n \t/*\n \t * We have x = bytes and y = microsecs.  We want z = KiB/s:\n \t *\n@@ -152,37 +150,37 @@ void display_throughput(struct progress *progress, unsigned long n)\n \n \tif (misecs > 512) {\n \t\tint l = sizeof(tp->display);\n+\t\tunsigned int count = total - tp->prev_total;\n+\t\ttp->prev_total = total;\n \t\ttp->prev_tv = tv;\n-\t\ttp->avg_bytes += tp->count;\n+\t\ttp->avg_bytes += count;\n \t\ttp->avg_misecs += misecs;\n \n-\t\tif (tp->total > 1 << 30) {\n+\t\tif (total > 1 << 30) {\n \t\t\tl -= snprintf(tp->display, l, \", %u.%2.2u GiB\",\n-\t\t\t\t      (int)(tp->total >> 30),\n-\t\t\t\t      (int)(tp->total & ((1 << 30) - 1)) / 10737419);\n-\t\t} else if (tp->total > 1 << 20) {\n+\t\t\t\t      (int)(total >> 30),\n+\t\t\t\t      (int)(total & ((1 << 30) - 1)) / 10737419);\n+\t\t} else if (total > 1 << 20) {\n \t\t\tl -= snprintf(tp->display, l, \", %u.%2.2u MiB\",\n-\t\t\t\t      (int)(tp->total >> 20),\n-\t\t\t\t      ((int)(tp->total & ((1 << 20) - 1))\n+\t\t\t\t      (int)(total >> 20),\n+\t\t\t\t      ((int)(total & ((1 << 20) - 1))\n \t\t\t\t       * 100) >> 20);\n-\t\t} else if (tp->total > 1 << 10) {\n+\t\t} else if (total > 1 << 10) {\n \t\t\tl -= snprintf(tp->display, l, \", %u.%2.2u KiB\",\n-\t\t\t\t      (int)(tp->total >> 10),\n-\t\t\t\t      ((int)(tp->total & ((1 << 10) - 1))\n+\t\t\t\t      (int)(total >> 10),\n+\t\t\t\t      ((int)(total & ((1 << 10) - 1))\n \t\t\t\t       * 100) >> 10);\n \t\t} else {\n-\t\t\tl -= snprintf(tp->display, l, \", %u bytes\",\n-\t\t\t\t      (int)tp->total);\n+\t\t\tl -= snprintf(tp->display, l, \", %u bytes\", (int)total);\n \t\t}\n \t\tsnprintf(tp->display + sizeof(tp->display) - l, l,\n-\t\t\t \" | %lu KiB/s\", tp->avg_bytes / tp->avg_misecs);\n+\t\t\t \" | %u KiB/s\", tp->avg_bytes / tp->avg_misecs);\n \n \t\ttp->avg_bytes -= tp->last_bytes[tp->idx];\n \t\ttp->avg_misecs -= tp->last_misecs[tp->idx];\n-\t\ttp->last_bytes[tp->idx] = tp->count;\n+\t\ttp->last_bytes[tp->idx] = count;\n \t\ttp->last_misecs[tp->idx] = misecs;\n \t\ttp->idx = (tp->idx + 1) % TP_IDX_MAX;\n-\t\ttp->count = 0;\n \n \t\tif (progress->last_value != -1 && progress_update)\n \t\t\tdisplay(progress, progress->last_value, 0);\ndiff --git a/progress.h b/progress.h\nindex 61cb68d..3912969 100644\n--- a/progress.h\n+++ b/progress.h\n@@ -3,7 +3,7 @@\n \n struct progress;\n \n-void display_throughput(struct progress *progress, unsigned long n);\n+void display_throughput(struct progress *progress, off_t total);\n int display_progress(struct progress *progress, unsigned n);\n struct progress *start_progress(const char *title, unsigned total);\n struct progress *start_progress_delay(const char *title, unsigned total,\n"}]}