{"thread":{"id":"10690","subject":"[PATCH] make display of total transferred fully accurate","startedAt":"2007-11-06T21:30:28Z","lastAt":"2007-11-06T21:30:28Z","messageCount":1,"participants":["Nicolas Pitre"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"58595","messageId":"alpine.LFD.0.9999.0711061608031.21255@xanadu.home","threadId":"10690","inReplyTo":null,"subject":"[PATCH] make display of total transferred fully accurate","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2007-11-06T21:30:28Z","receivedAt":"2007-11-06T21:30:28Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"The minimum delay of 1/2 sec between successive throughput updates might \nnot have been elapsed when display_throughput() is called for the last \ntime, potentially making the display of total transferred bytes not \nright when progress is said to be done.\n\nLet's force an update of the throughput display as well when the \nprogress is complete.  As a side effect, the total transferred will \nalways be displayed even if the actual transfer rate doesn't have time \nto kickin.\n\nSigned-off-by: Nicolas Pitre <nico@cam.org>\n---\n\nIt was seriously bugging me that the total still didn't match the size \nof received packs exactly, even after my previous attempt at fixing it.\n\ndiff --git a/progress.c b/progress.c\nindex a963bd8..2a5a2da 100644\n--- a/progress.c\n+++ b/progress.c\n@@ -14,11 +14,12 @@\n #define TP_IDX_MAX      8\n \n struct throughput {\n+\toff_t curr_total;\n \toff_t prev_total;\n \tstruct timeval prev_tv;\n \tunsigned int avg_bytes;\n-\tunsigned int last_bytes[TP_IDX_MAX];\n \tunsigned int avg_misecs;\n+\tunsigned int last_bytes[TP_IDX_MAX];\n \tunsigned int last_misecs[TP_IDX_MAX];\n \tunsigned int idx;\n \tchar display[32];\n@@ -109,6 +110,30 @@ static int display(struct progress *progress, unsigned n, int done)\n \treturn 0;\n }\n \n+static void throughput_string(struct throughput *tp, off_t total,\n+\t\t\t      unsigned int rate)\n+{\t\n+\tint l = sizeof(tp->display);\n+\tif (total > 1 << 30) {\n+\t\tl -= snprintf(tp->display, l, \", %u.%2.2u GiB\",\n+\t\t\t      (int)(total >> 30),\n+\t\t\t      (int)(total & ((1 << 30) - 1)) / 10737419);\n+\t} else if (total > 1 << 20) {\n+\t\tl -= snprintf(tp->display, l, \", %u.%2.2u MiB\",\n+\t\t\t      (int)(total >> 20),\n+\t\t\t      ((int)(total & ((1 << 20) - 1)) * 100) >> 20);\n+\t} else if (total > 1 << 10) {\n+\t\tl -= snprintf(tp->display, l, \", %u.%2.2u KiB\",\n+\t\t\t      (int)(total >> 10),\n+\t\t\t      ((int)(total & ((1 << 10) - 1)) * 100) >> 10);\n+\t} else {\n+\t\tl -= snprintf(tp->display, l, \", %u bytes\", (int)total);\n+\t}\n+\tif (rate)\n+\t\tsnprintf(tp->display + sizeof(tp->display) - l, l,\n+\t\t\t \" | %u KiB/s\", rate);\n+}\n+\n void display_throughput(struct progress *progress, off_t total)\n {\n \tstruct throughput *tp;\n@@ -124,11 +149,12 @@ void display_throughput(struct progress *progress, off_t total)\n \tif (!tp) {\n \t\tprogress->throughput = tp = calloc(1, sizeof(*tp));\n \t\tif (tp) {\n-\t\t\ttp->prev_total = total;\n+\t\t\ttp->prev_total = tp->curr_total = total;\n \t\t\ttp->prev_tv = tv;\n \t\t}\n \t\treturn;\n \t}\n+\ttp->curr_total = total;\n \n \t/*\n \t * We have x = bytes and y = microsecs.  We want z = KiB/s:\n@@ -149,39 +175,21 @@ void display_throughput(struct progress *progress, off_t total)\n \tmisecs += (int)(tv.tv_usec - tp->prev_tv.tv_usec) / 977;\n \n \tif (misecs > 512) {\n-\t\tint l = sizeof(tp->display);\n-\t\tunsigned int count = total - tp->prev_total;\n+\t\tunsigned int count, rate;\n+\t       \n+\t\tcount = total - tp->prev_total;\n \t\ttp->prev_total = total;\n \t\ttp->prev_tv = tv;\n \t\ttp->avg_bytes += count;\n \t\ttp->avg_misecs += misecs;\n-\n-\t\tif (total > 1 << 30) {\n-\t\t\tl -= snprintf(tp->display, l, \", %u.%2.2u GiB\",\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)(total >> 20),\n-\t\t\t\t      ((int)(total & ((1 << 20) - 1))\n-\t\t\t\t       * 100) >> 20);\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)(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\", (int)total);\n-\t\t}\n-\t\tsnprintf(tp->display + sizeof(tp->display) - l, l,\n-\t\t\t \" | %u KiB/s\", tp->avg_bytes / tp->avg_misecs);\n-\n+\t\trate = tp->avg_bytes / tp->avg_misecs;\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] = count;\n \t\ttp->last_misecs[tp->idx] = misecs;\n \t\ttp->idx = (tp->idx + 1) % TP_IDX_MAX;\n \n+\t\tthroughput_string(tp, total, rate);\n \t\tif (progress->last_value != -1 && progress_update)\n \t\t\tdisplay(progress, progress->last_value, 0);\n \t}\n@@ -225,6 +233,12 @@ void stop_progress(struct progress **p_progress)\n \t*p_progress = NULL;\n \tif (progress->last_value != -1) {\n \t\t/* Force the last update */\n+\t\tstruct throughput *tp = progress->throughput;\n+\t\tif (tp) {\n+\t\t\tunsigned int rate = !tp->avg_misecs ? 0 :\n+\t\t\t\t\ttp->avg_bytes / tp->avg_misecs;\n+\t\t\tthroughput_string(tp, tp->curr_total, rate);\n+\t\t}\n \t\tprogress_update = 1;\n \t\tdisplay(progress, progress->last_value, 1);\n \t}\n"}]}