X-Git-Url: http://sjero.net/git/?a=blobdiff_plain;f=src%2Fprogress.c;h=99bdd5b616881d06078eeb5de6768e6cb6f945c3;hb=5f0a2b3f0846dd4c2f72fc62e7171200d1fd6e06;hp=0e6267965047b0809618a53c3848050cbc65e9cc;hpb=9228f0bf53d3b42459daeb28372196a007de3014;p=wget diff --git a/src/progress.c b/src/progress.c index 0e626796..99bdd5b6 100644 --- a/src/progress.c +++ b/src/progress.c @@ -100,7 +100,7 @@ valid_progress_implementation_p (const char *name) char *colon = strchr (name, ':'); int namelen = colon ? colon - name : strlen (name); - for (i = 0; i < ARRAY_SIZE (implementations); i++, pi++) + for (i = 0; i < countof (implementations); i++, pi++) if (!strncmp (pi->name, name, namelen)) return 1; return 0; @@ -121,7 +121,7 @@ set_progress_implementation (const char *name) colon = strchr (name, ':'); namelen = colon ? colon - name : strlen (name); - for (i = 0; i < ARRAY_SIZE (implementations); i++, pi++) + for (i = 0; i < countof (implementations); i++, pi++) if (!strncmp (pi->name, name, namelen)) { current_impl = pi; @@ -206,10 +206,7 @@ struct dot_progress { static void * dot_create (long initial, long total) { - struct dot_progress *dp = xmalloc (sizeof (struct dot_progress)); - - memset (dp, 0, sizeof (*dp)); - + struct dot_progress *dp = xnew0 (struct dot_progress); dp->initial_length = initial; dp->total_length = total; @@ -414,13 +411,13 @@ dot_set_params (const char *params) static int screen_width = DEFAULT_SCREEN_WIDTH; /* Size of the download speed history ring. */ -#define DLSPEED_HISTORY_SIZE 30 +#define DLSPEED_HISTORY_SIZE 20 /* The minimum time length of a history sample. By default, each - sample is at least 100ms long, which means that, over the course of - 30 samples, "current" download speed spans at least 3s into the + sample is at least 150ms long, which means that, over the course of + 20 samples, "current" download speed spans at least 3s into the past. */ -#define DLSPEED_SAMPLE_MIN 100 +#define DLSPEED_SAMPLE_MIN 150 struct bar_progress { long initial_length; /* how many bytes have been downloaded @@ -477,9 +474,7 @@ static void display_image PARAMS ((char *)); static void * bar_create (long initial, long total) { - struct bar_progress *bp = xmalloc (sizeof (struct bar_progress)); - - memset (bp, 0, sizeof (*bp)); + struct bar_progress *bp = xnew0 (struct bar_progress); /* In theory, our callers should take care of this pathological case, but it can sometimes happen. */ @@ -561,19 +556,19 @@ bar_finish (void *progress, double dltime) speed, over the course of no less than 3s. (Shorter intervals produce very erratic results.) - To do so, it samples the speed in 0.1s intervals and stores the + To do so, it samples the speed in 150ms intervals and stores the recorded samples in a FIFO history ring. The ring stores no more - than 30 intervals, hence the history covers the period of at least - three seconds and at most 30 reads into the past. This method - should produce good results for both very fast and very slow - downloads. + than 20 intervals, hence the history covers the period of at least + three seconds and at most 20 reads into the past. This method + should produce reasonable results for downloads ranging from very + slow to very fast. The idea is that for fast downloads, we get the speed over exactly the last three seconds. For slow downloads (where a network read - takes more than 0.1s to complete), we get the speed over a larger + takes more than 150ms to complete), we get the speed over a larger time period, as large as it takes to complete thirty reads. This is good because slow downloads tend to fluctuate more and a - 3-second average would be very erratic. */ + 3-second average would be too erratic. */ static void update_speed_ring (struct bar_progress *bp, long howmuch, double dltime) @@ -688,29 +683,38 @@ create_image (struct bar_progress *bp, double dl_total_time) else APPEND_LITERAL (" "); - /* The progress bar: "[====> ]" */ + /* The progress bar: "[====> ]" or "[++==> ]". */ if (progress_size && bp->total_length > 0) { - double fraction = (double)size / bp->total_length; - int dlsz = (int)(fraction * progress_size); + /* Size of the initial portion. */ + int insz = (double)bp->initial_length / bp->total_length * progress_size; + + /* Size of the downloaded portion. */ + int dlsz = (double)size / bp->total_length * progress_size; + char *begin; + int i; assert (dlsz <= progress_size); + assert (insz <= dlsz); *p++ = '['; begin = p; + /* Print the initial portion of the download with '+' chars, the + rest with '=' and one '>'. */ + for (i = 0; i < insz; i++) + *p++ = '+'; + dlsz -= insz; if (dlsz > 0) { - /* Draw dlsz-1 '=' chars and one arrow char. */ - while (dlsz-- > 1) + for (i = 0; i < dlsz - 1; i++) *p++ = '='; *p++ = '>'; } while (p - begin < progress_size) *p++ = ' '; - *p++ = ']'; } else if (progress_size) @@ -749,16 +753,20 @@ create_image (struct bar_progress *bp, double dl_total_time) { static char *short_units[] = { "B/s", "K/s", "M/s", "G/s" }; int units = 0; - long bytes = hist->total_bytes + bp->recent_bytes; - double tm = hist->total_time + dl_total_time - bp->recent_start; - double dlrate = calc_rate (bytes, tm, &units); - sprintf (p, " %7.2f%s", dlrate, short_units[units]); + /* Calculate the download speed using the history ring and + recent data that hasn't made it to the ring yet. */ + long dlquant = hist->total_bytes + bp->recent_bytes; + double dltime = hist->total_time + (dl_total_time - bp->recent_start); + double dlspeed = calc_rate (dlquant, dltime, &units); + sprintf (p, " %7.2f%s", dlspeed, short_units[units]); p += strlen (p); } else APPEND_LITERAL (" --.--K/s"); - /* " ETA xx:xx:xx" */ + /* " ETA xx:xx:xx"; wait for three seconds before displaying the ETA. + That's because the ETA value needs a while to become + reliable. */ if (bp->total_length > 0 && dl_total_time > 3000) { long eta; @@ -767,8 +775,9 @@ create_image (struct bar_progress *bp, double dl_total_time) /* Don't change the value of ETA more than approximately once per second; doing so would cause flashing without providing any value to the user. */ - if (dl_total_time - bp->last_eta_time < 900 - && bp->last_eta_value != 0) + if (bp->total_length != size + && bp->last_eta_value != 0 + && dl_total_time - bp->last_eta_time < 900) eta = bp->last_eta_value; else {