Make "git clone" pack-fetching download statistics better
Average it out over a few events to make the numbers stable, and fix the silly usec->binary-ms conversion. Yeah, yeah, it's arguably eye-candy to keep the user calm, but let's do that right. Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
		
				
					committed by
					
						
						Junio C Hamano
					
				
			
			
				
	
			
			
			
						parent
						
							5ee2ad654b
						
					
				
				
					commit
					c548cf4ee0
				
			@ -130,12 +130,35 @@ int receive_unpack_pack(int fd[2], const char *me, int quiet)
 | 
			
		||||
	die("git-unpack-objects died of unnatural causes %d", status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * We average out the download speed over this many "events", where
 | 
			
		||||
 * an event is a minimum of about half a second. That way, we get
 | 
			
		||||
 * a reasonably stable number.
 | 
			
		||||
 */
 | 
			
		||||
#define NR_AVERAGE (4)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A "binary msec" is a power-of-two-msec, aka 1/1024th of a second.
 | 
			
		||||
 * Keeing the time in that format means that "bytes / msecs" means
 | 
			
		||||
 * is the same as kB/s (modulo rounding).
 | 
			
		||||
 *
 | 
			
		||||
 * 1000512 is a magic number (usecs in a second, rounded up by half
 | 
			
		||||
 * of 1024, to make "rounding" come out right ;)
 | 
			
		||||
 */
 | 
			
		||||
#define usec_to_binarymsec(x) ((int)(x) / (1000512 >> 10))
 | 
			
		||||
 | 
			
		||||
int receive_keep_pack(int fd[2], const char *me, int quiet)
 | 
			
		||||
{
 | 
			
		||||
	char tmpfile[PATH_MAX];
 | 
			
		||||
	int ofd, ifd;
 | 
			
		||||
	unsigned long total;
 | 
			
		||||
	static struct timeval prev_tv;
 | 
			
		||||
	struct average {
 | 
			
		||||
		unsigned long bytes;
 | 
			
		||||
		unsigned long time;
 | 
			
		||||
	} download[NR_AVERAGE] = { {0, 0}, };
 | 
			
		||||
	unsigned long avg_bytes, avg_time;
 | 
			
		||||
	int idx = 0;
 | 
			
		||||
 | 
			
		||||
	ifd = fd[0];
 | 
			
		||||
	snprintf(tmpfile, sizeof(tmpfile),
 | 
			
		||||
@ -146,6 +169,8 @@ int receive_keep_pack(int fd[2], const char *me, int quiet)
 | 
			
		||||
 | 
			
		||||
	gettimeofday(&prev_tv, NULL);
 | 
			
		||||
	total = 0;
 | 
			
		||||
	avg_bytes = 0;
 | 
			
		||||
	avg_time = 0;
 | 
			
		||||
	while (1) {
 | 
			
		||||
		char buf[8192];
 | 
			
		||||
		ssize_t sz, wsz, pos;
 | 
			
		||||
@ -181,14 +206,27 @@ int receive_keep_pack(int fd[2], const char *me, int quiet)
 | 
			
		||||
			gettimeofday(&tv, NULL);
 | 
			
		||||
			msecs = tv.tv_sec - prev_tv.tv_sec;
 | 
			
		||||
			msecs <<= 10;
 | 
			
		||||
			msecs += (int)(tv.tv_usec - prev_tv.tv_usec) >> 10;
 | 
			
		||||
			msecs += usec_to_binarymsec(tv.tv_usec - prev_tv.tv_usec);
 | 
			
		||||
 | 
			
		||||
			if (msecs > 500) {
 | 
			
		||||
				prev_tv = tv;
 | 
			
		||||
				last = total;
 | 
			
		||||
				fprintf(stderr, "%4lu.%03luMB  (%lu kB/s)        \r",
 | 
			
		||||
 | 
			
		||||
				/* Update averages ..*/
 | 
			
		||||
				avg_bytes += diff;
 | 
			
		||||
				avg_time += msecs;
 | 
			
		||||
				avg_bytes -= download[idx].bytes;
 | 
			
		||||
				avg_time -= download[idx].time;
 | 
			
		||||
				download[idx].bytes = diff;
 | 
			
		||||
				download[idx].time = msecs;
 | 
			
		||||
				idx++;
 | 
			
		||||
				if (idx >= NR_AVERAGE)
 | 
			
		||||
					idx = 0;
 | 
			
		||||
 | 
			
		||||
				fprintf(stderr, "%4lu.%03luMB  (%lu kB/s)      \r",
 | 
			
		||||
					total >> 20,
 | 
			
		||||
					1000*((total >> 10) & 1023)>>10,
 | 
			
		||||
					diff / msecs );
 | 
			
		||||
					avg_bytes / avg_time );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user