git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] add throughput to progress display
@ 2007-10-29 23:22 Nicolas Pitre
  2007-10-30  7:07 ` Johannes Sixt
  2007-10-30  8:29 ` Junio C Hamano
  0 siblings, 2 replies; 5+ messages in thread
From: Nicolas Pitre @ 2007-10-29 23:22 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

This adds the ability for the progress code to also display throughput
when that makes sense.

The math was inspired by commit c548cf4ee0737a321ffe94f6a97c65baf87281be
from Linus.

Signed-off-by: Nicolas Pitre <nico@cam.org>
---

diff --git a/progress.c b/progress.c
index 7629e05..275579b 100644
--- a/progress.c
+++ b/progress.c
@@ -37,7 +37,7 @@ static void clear_progress_signal(void)
 
 static int display(struct progress *progress, unsigned n, int done)
 {
-	char *eol;
+	char *eol, *tp;
 
 	if (progress->delay) {
 		if (!progress_update || --progress->delay)
@@ -55,18 +55,20 @@ static int display(struct progress *progress, unsigned n, int done)
 	}
 
 	progress->last_value = n;
+	tp = (progress->throughput) ? progress->throughput->display : "";
 	eol = done ? ", done.   \n" : "   \r";
 	if (progress->total) {
 		unsigned percent = n * 100 / progress->total;
 		if (percent != progress->last_percent || progress_update) {
 			progress->last_percent = percent;
-			fprintf(stderr, "%s: %3u%% (%u/%u)%s", progress->title,
-				percent, n, progress->total, eol);
+			fprintf(stderr, "%s: %3u%% (%u/%u)%s%s",
+				progress->title, percent, n,
+				progress->total, tp, eol);
 			progress_update = 0;
 			return 1;
 		}
 	} else if (progress_update) {
-		fprintf(stderr, "%s: %u%s", progress->title, n, eol);
+		fprintf(stderr, "%s: %u%s%s", progress->title, n, tp, eol);
 		progress_update = 0;
 		return 1;
 	}
@@ -74,6 +76,59 @@ static int display(struct progress *progress, unsigned n, int done)
 	return 0;
 }
 
+void display_throughput(struct progress *progress, unsigned long n)
+{
+	struct throughput *tp = progress->throughput;
+	struct timeval tv;
+	unsigned int misecs;
+	
+	gettimeofday(&tv, NULL);
+
+	if (!tp) {
+		progress->throughput = tp = calloc(1, sizeof(*tp));
+		if (tp)
+			tp->prev_tv = tv;
+		return;
+	}
+
+	tp->count += n;
+
+	/*
+	 * We have x = bytes and y = microsecs.  We want z = KiB/s:
+	 *
+	 *	z = (x / 1024) / (y / 1000000)
+	 *	z = x / y * 1000000 / 1024
+	 *	z = x / (y * 1024 / 1000000)
+	 *	z = x / y'
+	 *
+	 * To simplify things we'll keep track of misecs, or 1024th of a sec
+	 * obtained with:
+	 *
+	 *	y' = y * 1024 / 1000000
+	 *
+	 * Taking care not to overflow y' we get:
+	 *
+	 *	y' = y / (1000000 / 1024)
+	 *	y' = y / 977
+	 */
+	misecs = (tv.tv_sec - tp->prev_tv.tv_sec) * 1024;
+	misecs += (int)(tv.tv_usec - tp->prev_tv.tv_usec) / 977;
+
+	if (misecs > 512) {
+		tp->prev_tv = tv;
+		tp->avg_bytes += tp->count;
+		tp->avg_misecs += misecs;
+		snprintf(tp->display, sizeof(tp->display),
+			 ", %lu 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_misecs[tp->idx] = misecs;
+		tp->idx = (tp->idx + 1) % TP_IDX_MAX;
+		tp->count = 0;
+	}
+}
+
 int display_progress(struct progress *progress, unsigned n)
 {
 	return display(progress, n, 0);
@@ -104,4 +159,6 @@ void stop_progress(struct progress *progress)
 		display(progress, progress->last_value, 1);
 	}
 	clear_progress_signal();
+	free(progress->throughput);
+	progress->throughput = NULL;
 }
diff --git a/progress.h b/progress.h
index 07b56bd..eba457f 100644
--- a/progress.h
+++ b/progress.h
@@ -1,6 +1,21 @@
 #ifndef PROGRESS_H
 #define PROGRESS_H
 
+#include <sys/time.h>
+
+#define TP_IDX_MAX	8
+
+struct throughput {
+	struct timeval prev_tv;
+	unsigned long count;
+	unsigned long avg_bytes;
+	unsigned long last_bytes[TP_IDX_MAX];
+	unsigned int avg_misecs;
+	unsigned int last_misecs[TP_IDX_MAX];
+	unsigned int idx;
+	char display[20];
+};
+
 struct progress {
 	const char *title;
 	int last_value;
@@ -8,8 +23,10 @@ struct progress {
 	unsigned last_percent;
 	unsigned delay;
 	unsigned delayed_percent_treshold;
+	struct throughput *throughput;
 };
 
+void display_throughput(struct progress *progress, unsigned long n);
 int display_progress(struct progress *progress, unsigned n);
 void start_progress(struct progress *progress, const char *title,
 		    unsigned total);

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] add throughput to progress display
  2007-10-29 23:22 [PATCH 1/2] add throughput to progress display Nicolas Pitre
@ 2007-10-30  7:07 ` Johannes Sixt
  2007-10-30  8:29 ` Junio C Hamano
  1 sibling, 0 replies; 5+ messages in thread
From: Johannes Sixt @ 2007-10-30  7:07 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: Junio C Hamano, git

Nicolas Pitre schrieb:
> diff --git a/progress.h b/progress.h
> index 07b56bd..eba457f 100644
> --- a/progress.h
> +++ b/progress.h
> @@ -1,6 +1,21 @@
>  #ifndef PROGRESS_H
>  #define PROGRESS_H
>  
> +#include <sys/time.h>

System headers should be taken care of by git-compat-util.h. In fact, it 
already pulls in <sys/time.h>, hence, it shouldn't be necessary here.

-- Hannes

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] add throughput to progress display
  2007-10-29 23:22 [PATCH 1/2] add throughput to progress display Nicolas Pitre
  2007-10-30  7:07 ` Johannes Sixt
@ 2007-10-30  8:29 ` Junio C Hamano
  2007-10-30 13:43   ` Nicolas Pitre
  1 sibling, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2007-10-30  8:29 UTC (permalink / raw)
  To: Nicolas Pitre; +Cc: git

Very nice.

I however wonder why this breaks t1004 when applied on top of
lt/rename topic.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] add throughput to progress display
  2007-10-30  8:29 ` Junio C Hamano
@ 2007-10-30 13:43   ` Nicolas Pitre
  2007-10-30 13:54     ` Nicolas Pitre
  0 siblings, 1 reply; 5+ messages in thread
From: Nicolas Pitre @ 2007-10-30 13:43 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Tue, 30 Oct 2007, Junio C Hamano wrote:

> Very nice.
> 
> I however wonder why this breaks t1004 when applied on top of
> lt/rename topic.

Well... sh*t happens.

Could you please simply amend [PATCH 1/2] with the patch below:

diff --git a/progress.c b/progress.c
index d2460dd..a388e54 100644
--- a/progress.c
+++ b/progress.c
@@ -143,6 +143,7 @@ void start_progress_delay(struct progress *progress, const char *title,
 	progress->last_percent = -1;
 	progress->delayed_percent_treshold = percent_treshold;
 	progress->delay = delay;
+	progress->throughput = NULL;
 	set_progress_signal();
 }
 
@@ -160,5 +161,4 @@ void stop_progress(struct progress *progress)
 	}
 	clear_progress_signal();
 	free(progress->throughput);
-	progress->throughput = NULL;
 }


Nicolas

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] add throughput to progress display
  2007-10-30 13:43   ` Nicolas Pitre
@ 2007-10-30 13:54     ` Nicolas Pitre
  0 siblings, 0 replies; 5+ messages in thread
From: Nicolas Pitre @ 2007-10-30 13:54 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Tue, 30 Oct 2007, Nicolas Pitre wrote:

> On Tue, 30 Oct 2007, Junio C Hamano wrote:
> 
> > Very nice.
> > 
> > I however wonder why this breaks t1004 when applied on top of
> > lt/rename topic.
> 
> Well... sh*t happens.
> 
> Could you please simply amend [PATCH 1/2] with the patch below:

Well that isn't enough.  Please just scrap the whole thing as more 
fundamental changes are needed.  I'll send a new patch set when ready.


Nicolas

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-10-30 13:54 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-29 23:22 [PATCH 1/2] add throughput to progress display Nicolas Pitre
2007-10-30  7:07 ` Johannes Sixt
2007-10-30  8:29 ` Junio C Hamano
2007-10-30 13:43   ` Nicolas Pitre
2007-10-30 13:54     ` Nicolas Pitre

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).