{"thread":{"id":"10510","subject":"[PATCH 1/2] add throughput to progress display","startedAt":"2007-10-29T23:22:20Z","lastAt":"2007-10-30T13:54:45Z","messageCount":5,"participants":["Nicolas Pitre","Johannes Sixt","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"57495","messageId":"alpine.LFD.0.9999.0710291904190.22100@xanadu.home","threadId":"10510","inReplyTo":null,"subject":"[PATCH 1/2] add throughput to progress display","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2007-10-29T23:22:20Z","receivedAt":"2007-10-29T23:22:20Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"This adds the ability for the progress code to also display throughput\nwhen that makes sense.\n\nThe math was inspired by commit c548cf4ee0737a321ffe94f6a97c65baf87281be\nfrom Linus.\n\nSigned-off-by: Nicolas Pitre <nico@cam.org>\n---\n\ndiff --git a/progress.c b/progress.c\nindex 7629e05..275579b 100644\n--- a/progress.c\n+++ b/progress.c\n@@ -37,7 +37,7 @@ static void clear_progress_signal(void)\n \n static int display(struct progress *progress, unsigned n, int done)\n {\n-\tchar *eol;\n+\tchar *eol, *tp;\n \n \tif (progress->delay) {\n \t\tif (!progress_update || --progress->delay)\n@@ -55,18 +55,20 @@ static int display(struct progress *progress, unsigned n, int done)\n \t}\n \n \tprogress->last_value = n;\n+\ttp = (progress->throughput) ? progress->throughput->display : \"\";\n \teol = done ? \", done.   \\n\" : \"   \\r\";\n \tif (progress->total) {\n \t\tunsigned percent = n * 100 / progress->total;\n \t\tif (percent != progress->last_percent || progress_update) {\n \t\t\tprogress->last_percent = percent;\n-\t\t\tfprintf(stderr, \"%s: %3u%% (%u/%u)%s\", progress->title,\n-\t\t\t\tpercent, n, progress->total, eol);\n+\t\t\tfprintf(stderr, \"%s: %3u%% (%u/%u)%s%s\",\n+\t\t\t\tprogress->title, percent, n,\n+\t\t\t\tprogress->total, tp, eol);\n \t\t\tprogress_update = 0;\n \t\t\treturn 1;\n \t\t}\n \t} else if (progress_update) {\n-\t\tfprintf(stderr, \"%s: %u%s\", progress->title, n, eol);\n+\t\tfprintf(stderr, \"%s: %u%s%s\", progress->title, n, tp, eol);\n \t\tprogress_update = 0;\n \t\treturn 1;\n \t}\n@@ -74,6 +76,59 @@ 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+{\n+\tstruct throughput *tp = progress->throughput;\n+\tstruct timeval tv;\n+\tunsigned int misecs;\n+\t\n+\tgettimeofday(&tv, NULL);\n+\n+\tif (!tp) {\n+\t\tprogress->throughput = tp = calloc(1, sizeof(*tp));\n+\t\tif (tp)\n+\t\t\ttp->prev_tv = tv;\n+\t\treturn;\n+\t}\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+\t *\tz = (x / 1024) / (y / 1000000)\n+\t *\tz = x / y * 1000000 / 1024\n+\t *\tz = x / (y * 1024 / 1000000)\n+\t *\tz = x / y'\n+\t *\n+\t * To simplify things we'll keep track of misecs, or 1024th of a sec\n+\t * obtained with:\n+\t *\n+\t *\ty' = y * 1024 / 1000000\n+\t *\n+\t * Taking care not to overflow y' we get:\n+\t *\n+\t *\ty' = y / (1000000 / 1024)\n+\t *\ty' = y / 977\n+\t */\n+\tmisecs = (tv.tv_sec - tp->prev_tv.tv_sec) * 1024;\n+\tmisecs += (int)(tv.tv_usec - tp->prev_tv.tv_usec) / 977;\n+\n+\tif (misecs > 512) {\n+\t\ttp->prev_tv = tv;\n+\t\ttp->avg_bytes += tp->count;\n+\t\ttp->avg_misecs += misecs;\n+\t\tsnprintf(tp->display, sizeof(tp->display),\n+\t\t\t \", %lu KiB/s\", 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] = tp->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+\t}\n+}\n+\n int display_progress(struct progress *progress, unsigned n)\n {\n \treturn display(progress, n, 0);\n@@ -104,4 +159,6 @@ void stop_progress(struct progress *progress)\n \t\tdisplay(progress, progress->last_value, 1);\n \t}\n \tclear_progress_signal();\n+\tfree(progress->throughput);\n+\tprogress->throughput = NULL;\n }\ndiff --git a/progress.h b/progress.h\nindex 07b56bd..eba457f 100644\n--- a/progress.h\n+++ b/progress.h\n@@ -1,6 +1,21 @@\n #ifndef PROGRESS_H\n #define PROGRESS_H\n \n+#include <sys/time.h>\n+\n+#define TP_IDX_MAX\t8\n+\n+struct throughput {\n+\tstruct timeval prev_tv;\n+\tunsigned long count;\n+\tunsigned long avg_bytes;\n+\tunsigned long last_bytes[TP_IDX_MAX];\n+\tunsigned int avg_misecs;\n+\tunsigned int last_misecs[TP_IDX_MAX];\n+\tunsigned int idx;\n+\tchar display[20];\n+};\n+\n struct progress {\n \tconst char *title;\n \tint last_value;\n@@ -8,8 +23,10 @@ struct progress {\n \tunsigned last_percent;\n \tunsigned delay;\n \tunsigned delayed_percent_treshold;\n+\tstruct throughput *throughput;\n };\n \n+void display_throughput(struct progress *progress, unsigned long n);\n int display_progress(struct progress *progress, unsigned n);\n void start_progress(struct progress *progress, const char *title,\n \t\t    unsigned total);\n"},{"id":"57533","messageId":"4726D833.90800@viscovery.net","threadId":"10510","inReplyTo":"alpine.LFD.0.9999.0710291904190.22100@xanadu.home","subject":"Re: [PATCH 1/2] add throughput to progress display","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2007-10-30T07:07:31Z","receivedAt":"2007-10-30T07:07:31Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Nicolas Pitre schrieb:\n> diff --git a/progress.h b/progress.h\n> index 07b56bd..eba457f 100644\n> --- a/progress.h\n> +++ b/progress.h\n> @@ -1,6 +1,21 @@\n>  #ifndef PROGRESS_H\n>  #define PROGRESS_H\n>  \n> +#include <sys/time.h>\n\nSystem headers should be taken care of by git-compat-util.h. In fact, it \nalready pulls in <sys/time.h>, hence, it shouldn't be necessary here.\n\n-- Hannes\n"},{"id":"57544","messageId":"7vr6jdm2eb.fsf@gitster.siamese.dyndns.org","threadId":"10510","inReplyTo":"alpine.LFD.0.9999.0710291904190.22100@xanadu.home","subject":"Re: [PATCH 1/2] add throughput to progress display","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-10-30T08:29:16Z","receivedAt":"2007-10-30T08:29:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Very nice.\n\nI however wonder why this breaks t1004 when applied on top of\nlt/rename topic.\n"},{"id":"57572","messageId":"alpine.LFD.0.9999.0710300935330.21255@xanadu.home","threadId":"10510","inReplyTo":"7vr6jdm2eb.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH 1/2] add throughput to progress display","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2007-10-30T13:43:53Z","receivedAt":"2007-10-30T13:43:53Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Tue, 30 Oct 2007, Junio C Hamano wrote:\n\n> Very nice.\n> \n> I however wonder why this breaks t1004 when applied on top of\n> lt/rename topic.\n\nWell... sh*t happens.\n\nCould you please simply amend [PATCH 1/2] with the patch below:\n\ndiff --git a/progress.c b/progress.c\nindex d2460dd..a388e54 100644\n--- a/progress.c\n+++ b/progress.c\n@@ -143,6 +143,7 @@ void start_progress_delay(struct progress *progress, const char *title,\n \tprogress->last_percent = -1;\n \tprogress->delayed_percent_treshold = percent_treshold;\n \tprogress->delay = delay;\n+\tprogress->throughput = NULL;\n \tset_progress_signal();\n }\n \n@@ -160,5 +161,4 @@ void stop_progress(struct progress *progress)\n \t}\n \tclear_progress_signal();\n \tfree(progress->throughput);\n-\tprogress->throughput = NULL;\n }\n\n\nNicolas\n"},{"id":"57576","messageId":"alpine.LFD.0.9999.0710300952520.21255@xanadu.home","threadId":"10510","inReplyTo":"alpine.LFD.0.9999.0710300935330.21255@xanadu.home","subject":"Re: [PATCH 1/2] add throughput to progress display","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2007-10-30T13:54:45Z","receivedAt":"2007-10-30T13:54:45Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Tue, 30 Oct 2007, Nicolas Pitre wrote:\n\n> On Tue, 30 Oct 2007, Junio C Hamano wrote:\n> \n> > Very nice.\n> > \n> > I however wonder why this breaks t1004 when applied on top of\n> > lt/rename topic.\n> \n> Well... sh*t happens.\n> \n> Could you please simply amend [PATCH 1/2] with the patch below:\n\nWell that isn't enough.  Please just scrap the whole thing as more \nfundamental changes are needed.  I'll send a new patch set when ready.\n\n\nNicolas\n"}]}