]> sjero.net Git - wget/blobdiff - src/progress.c
[svn] Use new macros xnew, xnew0, xnew_array, and xnew0_array in various places.
[wget] / src / progress.c
index ab99caf1113c884348d6f928b3c323833b4e7862..99bdd5b616881d06078eeb5de6768e6cb6f945c3 100644 (file)
@@ -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
        {