Please find attached...

The quick test:

If you run wget with --limit-percent 50, you should see it run at full
blast for 15 seconds and then back off till it's downloading at 50%
the rate it acheived in the first 15 seconds.

This is only the initial Works For Me version of the patch.  Comments
welcome, as anyone else who wants to run with it is welcome to do so.

Best Regards.
Tony

PS to Micah: Yes, I changed pct to percent.
diff --git a/src/init.c b/src/init.c
--- a/src/init.c
+++ b/src/init.c
@@ -179,6 +179,7 @@ static const struct {
 #endif
   { "input",            &opt.input_filename,    cmd_file },
   { "keepsessioncookies", &opt.keep_session_cookies, cmd_boolean },
+  { "limitpercent",     &opt.limit_percent,     cmd_number },
   { "limitrate",        &opt.limit_rate,        cmd_bytes },
   { "loadcookies",      &opt.cookies_input,     cmd_file },
   { "logfile",          &opt.lfilename,         cmd_file },
diff --git a/src/main.c b/src/main.c
--- a/src/main.c
+++ b/src/main.c
@@ -189,6 +189,7 @@ static struct cmdline_option option_data
     { "input-file", 'i', OPT_VALUE, "input", -1 },
     { "keep-session-cookies", 0, OPT_BOOLEAN, "keepsessioncookies", -1 },
     { "level", 'l', OPT_VALUE, "reclevel", -1 },
+    { "limit-percent", 0, OPT_VALUE, "limitpercent", -1 },
     { "limit-rate", 0, OPT_VALUE, "limitrate", -1 },
     { "load-cookies", 0, OPT_VALUE, "loadcookies", -1 },
     { "max-redirect", 0, OPT_VALUE, "maxredirect", -1 },
@@ -453,6 +454,10 @@ Download:\n"),
   -Q,  --quota=NUMBER            set retrieval quota to NUMBER.\n"),
     N_("\
        --bind-address=ADDRESS    bind to ADDRESS (hostname or IP) on local host.\n"),
+    N_("\
+       --limit-percent=NUMBER    limit download rate to NUMBER percent of measured initial burst\n"),
+    N_("\
+                                 or rate specified by --limit-rate\n"),
     N_("\
        --limit-rate=RATE         limit download rate to RATE.\n"),
     N_("\
diff --git a/src/options.h b/src/options.h
--- a/src/options.h
+++ b/src/options.h
@@ -115,6 +115,8 @@ struct options
   double waitretry;		/* The wait period between retries. - HEH */
   bool use_robots;		/* Do we heed robots.txt? */
 
+  wgint limit_percent;		/* Limit the download rate to this percentage
+                                   of initial measured burst rate. */
   wgint limit_rate;		/* Limit the download rate to this
 				   many bps. */
   SUM_SIZE_INT quota;		/* Maximum file size to download and
diff --git a/src/retr.c b/src/retr.c
--- a/src/retr.c
+++ b/src/retr.c
@@ -86,14 +86,61 @@ limit_bandwidth (wgint bytes, struct pti
 limit_bandwidth (wgint bytes, struct ptimer *timer)
 {
   double delta_t = ptimer_read (timer) - limit_data.chunk_start;
-  double expected;
+  double expected= 0.0;
 
   limit_data.chunk_bytes += bytes;
 
+  static wgint measured_limit= 0;
+
+  wgint limit= 0;
+
+  if ( opt.limit_rate )
+  {
+    limit= opt.limit_rate;
+
+    if ( opt.limit_percent )
+    {
+      limit= limit * opt.limit_percent / 100;
+    }
+    DEBUGP(("fixed limit governs: %lld bps\n", limit));
+  }
+  else
+  if ( opt.limit_percent )
+  {
+    if ( ! measured_limit )
+    {
+      static double total_sec= 0.0;
+      static wgint total_bytes= 0;
+
+      total_sec += delta_t;
+      total_bytes += bytes;
+      const double MEASURE_SEC= 15.0;
+
+      if ( total_sec > MEASURE_SEC )
+      {
+        DEBUGP(("After %.3f seconds we saw %lld bytes so our measured limit is %lld bps\n",
+                total_sec / 1000, total_bytes, measured_limit ));
+        measured_limit = total_bytes / total_sec * opt.limit_percent / 100.0;
+      }
+    }
+
+    if ( measured_limit )
+    {
+      if ( !limit || measured_limit < limit )
+      {
+        limit= measured_limit;
+      }
+    }
+  }
+
+  if ( limit )
+  {
+
   /* Calculate the amount of time we expect downloading the chunk
-     should take.  If in reality it took less time, sleep to
-     compensate for the difference.  */
-  expected = (double) limit_data.chunk_bytes / opt.limit_rate;
+     should take at this fixed rate.  If in reality it took less time, 
+     sleep to compensate for the difference.  */
+
+  expected = (double) limit_data.chunk_bytes / limit;
 
   if (expected > delta_t)
     {
@@ -127,6 +174,8 @@ limit_bandwidth (wgint bytes, struct pti
         limit_data.sleep_adjust = -0.5;
     }
 
+  }
+
   limit_data.chunk_bytes = 0;
   limit_data.chunk_start = ptimer_read (timer);
 }
@@ -229,13 +278,13 @@ fd_read_body (int fd, FILE *out, wgint t
       progress_interactive = progress_interactive_p (progress);
     }
 
-  if (opt.limit_rate)
+  if (opt.limit_rate || opt.limit_percent)
     limit_bandwidth_reset ();
 
   /* A timer is needed for tracking progress, for throttling, and for
      tracking elapsed time.  If either of these are requested, start
      the timer.  */
-  if (progress || opt.limit_rate || elapsed)
+  if (progress || opt.limit_rate || opt.limit_percent || elapsed)
     {
       timer = ptimer_new ();
       last_successful_read_tm = 0;
@@ -286,7 +335,7 @@ fd_read_body (int fd, FILE *out, wgint t
       else if (ret <= 0)
         break;                  /* EOF or read error */
 
-      if (progress || opt.limit_rate)
+      if (progress || opt.limit_rate || opt.limit_percent)
         {
           ptimer_measure (timer);
           if (ret > 0)
@@ -303,7 +352,7 @@ fd_read_body (int fd, FILE *out, wgint t
             }
         }
 
-      if (opt.limit_rate)
+      if (opt.limit_rate || opt.limit_percent)
         limit_bandwidth (ret, timer);
 
       if (progress)

Reply via email to