On Wed, 17 Apr 2002, Hrvoje Niksic wrote:

> Roger, thanks for this patch, but that's not quite what I had in
> mind.  Specifically, I'd like to keep calculating the download speed
> exactly as now -- based only on current timings.
>
> However, I would like the ETA to be based on the smarter model of
> predicting overall speed.  I'll try to modify your code to only use
> the exponential decay model for the ETA.

This secondary patch should do that:

--- src/progress.c.patched      Tue Apr 16 19:04:42 2002
+++ src/progress.c      Tue Apr 16 19:07:43 2002
@@ -604,32 +604,6 @@
 # define MAX(a, b) ((a) >= (b) ? (a) : (b))
 #endif

-/* Trim the download rate as appropriate for the speed.  Appropriate
-   means that if rate is greater than 1K/s, kilobytes are used, and
-   if rate is greater than 1MB/s, megabytes are used.
-
-   UNITS is zero for B/s, one for KB/s, two for MB/s, and three for
-   GB/s.  */
-double
-trim_rate (double raw_rate, int *units)
-{
-  double dlrate;
-
- dlrate = raw_rate * 1000;
-  if (dlrate < 1024.0)
-    *units = 0;
-  else if (dlrate < 1024.0 * 1024.0)
-    *units = 1, dlrate /= 1024.0;
-  else if (dlrate < 1024.0 * 1024.0 * 1024.0)
-    *units = 2, dlrate /= (1024.0 * 1024.0);
-  else
-    /* Maybe someone will need this one day.  More realistically, it
-       will get tickled by buggy timers. */
-    *units = 3, dlrate /= (1024.0 * 1024.0 * 1024.0);
-
-  return dlrate;
-}
-
 static void
 create_image (struct bar_progress *bp, long dl_total_time)
 {
@@ -764,7 +738,6 @@
     {
       if (bp->last_screen_update < RATE_INTERVAL)
         {
-           ddlrate = calc_rate (bp->count, dl_total_time, &units);
            bp->rate_decay = (double) bp->count / dl_total_time;
         }
       else
@@ -777,8 +750,8 @@
           bp->rate_decay = ( (bp->rate_decay - this_dlrate) *
                              pow (DECAY_EXPN, decay_int) ) +
                              this_dlrate;
-          ddlrate = trim_rate (bp->rate_decay, &units);
         }
+      ddlrate = calc_rate (bp->count, dl_total_time, &units);
       sprintf (p, " %7.2f%s", ddlrate, short_units[units]);
       p += strlen (p);
     }

-------- end of patch --------

Again this is just code to show the algorithm. The basic idea is
like you suggested, keep an "average" and "average" that with the
new value.  This would be very easy if the measurement interval
were constant. The pow function is used to normalize the values
based on the variable measurement interval. Notice that if the
measurement interval is equal to RATE_INTERVAL the caclulation
boils down to (old-value + new-value) / 2.

Roger L. Beeman

Reply via email to