Skip to content

Commit c548cf4

Browse files
Linus TorvaldsJunio C Hamano
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5ee2ad6 commit c548cf4

File tree

1 file changed

+41
-3
lines changed

1 file changed

+41
-3
lines changed

fetch-clone.c

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,35 @@ int receive_unpack_pack(int fd[2], const char *me, int quiet)
130130
die("git-unpack-objects died of unnatural causes %d", status);
131131
}
132132

133+
/*
134+
* We average out the download speed over this many "events", where
135+
* an event is a minimum of about half a second. That way, we get
136+
* a reasonably stable number.
137+
*/
138+
#define NR_AVERAGE (4)
139+
140+
/*
141+
* A "binary msec" is a power-of-two-msec, aka 1/1024th of a second.
142+
* Keeing the time in that format means that "bytes / msecs" means
143+
* is the same as kB/s (modulo rounding).
144+
*
145+
* 1000512 is a magic number (usecs in a second, rounded up by half
146+
* of 1024, to make "rounding" come out right ;)
147+
*/
148+
#define usec_to_binarymsec(x) ((int)(x) / (1000512 >> 10))
149+
133150
int receive_keep_pack(int fd[2], const char *me, int quiet)
134151
{
135152
char tmpfile[PATH_MAX];
136153
int ofd, ifd;
137154
unsigned long total;
138155
static struct timeval prev_tv;
156+
struct average {
157+
unsigned long bytes;
158+
unsigned long time;
159+
} download[NR_AVERAGE] = { {0, 0}, };
160+
unsigned long avg_bytes, avg_time;
161+
int idx = 0;
139162

140163
ifd = fd[0];
141164
snprintf(tmpfile, sizeof(tmpfile),
@@ -146,6 +169,8 @@ int receive_keep_pack(int fd[2], const char *me, int quiet)
146169

147170
gettimeofday(&prev_tv, NULL);
148171
total = 0;
172+
avg_bytes = 0;
173+
avg_time = 0;
149174
while (1) {
150175
char buf[8192];
151176
ssize_t sz, wsz, pos;
@@ -181,14 +206,27 @@ int receive_keep_pack(int fd[2], const char *me, int quiet)
181206
gettimeofday(&tv, NULL);
182207
msecs = tv.tv_sec - prev_tv.tv_sec;
183208
msecs <<= 10;
184-
msecs += (int)(tv.tv_usec - prev_tv.tv_usec) >> 10;
209+
msecs += usec_to_binarymsec(tv.tv_usec - prev_tv.tv_usec);
210+
185211
if (msecs > 500) {
186212
prev_tv = tv;
187213
last = total;
188-
fprintf(stderr, "%4lu.%03luMB (%lu kB/s) \r",
214+
215+
/* Update averages ..*/
216+
avg_bytes += diff;
217+
avg_time += msecs;
218+
avg_bytes -= download[idx].bytes;
219+
avg_time -= download[idx].time;
220+
download[idx].bytes = diff;
221+
download[idx].time = msecs;
222+
idx++;
223+
if (idx >= NR_AVERAGE)
224+
idx = 0;
225+
226+
fprintf(stderr, "%4lu.%03luMB (%lu kB/s) \r",
189227
total >> 20,
190228
1000*((total >> 10) & 1023)>>10,
191-
diff / msecs );
229+
avg_bytes / avg_time );
192230
}
193231
}
194232
}

0 commit comments

Comments
 (0)