Progress indicator now shows estimated rate of transfer (e.g. kB/s).
authorMartin Pool <mbp@samba.org>
Sun, 2 Dec 2001 08:38:51 +0000 (08:38 +0000)
committerMartin Pool <mbp@samba.org>
Sun, 2 Dec 2001 08:38:51 +0000 (08:38 +0000)
Based on a patch from Rik Faith, but modified to make sure we do only
one rprintf call, and that we never end up with two copies of the line
printed out.

util.c

diff --git a/util.c b/util.c
index ada404653e3b615135f4c8e5a5a01fd6cfaa61ed..3fd65f4f8c791d6d3a02b01bbc44694ad497e777 100644 (file)
--- a/util.c
+++ b/util.c
@@ -811,28 +811,84 @@ int u_strcmp(const char *cs1, const char *cs2)
        return (int)*s1 - (int)*s2;
 }
 
        return (int)*s1 - (int)*s2;
 }
 
-static OFF_T last_ofs;
+static OFF_T  last_ofs;
+static struct timeval print_time;
+static struct timeval start_time;
+static OFF_T  start_ofs;
+
+static unsigned long msdiff(struct timeval *t1, struct timeval *t2)
+{
+    return (t2->tv_sec - t1->tv_sec) * 1000
+        + (t2->tv_usec - t1->tv_usec) / 1000;
+}
+
+
+/**
+ * @param is_last True if this is the last time progress will be
+ * printed for this file, so we should output a newline.  (Not
+ * necessarily the same as all bytes being received.)
+ **/
+static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
+                           int is_last)
+{
+    int           pct  = (int)((100.0*ofs)/size);
+    unsigned long diff = msdiff(&start_time, now);
+    double        rate = diff ? ((ofs-start_ofs) / diff) * 1000.0/1024.0 : 0;
+    const char    *units;
+
+    if (ofs == size) pct = 100;
+    
+    if (rate > 1024*1024) {
+           rate /= 1024.0 * 1024.0;
+           units = "GB/s";
+    } else if (rate > 1024) {
+           rate /= 1024.0;
+           units = "MB/s";
+    } else {
+           units = "kB/s";
+    }
+    
+    rprintf(FINFO, "%12.0f %3d%% %7.2f%s%s",
+           (double) ofs, pct, rate, units,
+           is_last ? "\n" : "\r");
+}
 
 void end_progress(OFF_T size)
 {
        extern int do_progress, am_server;
 
        if (do_progress && !am_server) {
 
 void end_progress(OFF_T size)
 {
        extern int do_progress, am_server;
 
        if (do_progress && !am_server) {
-               rprintf(FINFO,"%.0f (100%%)\n", (double)size);
+               struct timeval now;
+                gettimeofday(&now, NULL);
+                rprint_progress(size, size, &now, True);
        }
        }
-       last_ofs = 0;
+       last_ofs   = 0;
+        start_ofs  = 0;
+        print_time.tv_sec  = print_time.tv_usec  = 0;
+        start_time.tv_sec  = start_time.tv_usec  = 0;
 }
 
 void show_progress(OFF_T ofs, OFF_T size)
 {
        extern int do_progress, am_server;
 }
 
 void show_progress(OFF_T ofs, OFF_T size)
 {
        extern int do_progress, am_server;
-
-       if (do_progress && !am_server) {
-               if (ofs > last_ofs + 1000) {
-                       int pct = (int)((100.0*ofs)/size);
-                       rprintf(FINFO,"%.0f (%d%%)\r", (double)ofs, pct);
-                       last_ofs = ofs;
-               }
+        struct timeval now;
+
+        gettimeofday(&now, NULL);
+
+        if (!start_time.tv_sec && !start_time.tv_usec) {
+               start_time.tv_sec  = now.tv_sec;
+                start_time.tv_usec = now.tv_usec;
+                start_ofs          = ofs;
+        }
+
+       if (do_progress
+            && !am_server
+            && ofs > last_ofs + 1000
+            && msdiff(&print_time, &now) > 250) {
+               rprint_progress(ofs, size, &now, False);
+                last_ofs = ofs;
+                print_time.tv_sec  = now.tv_sec;
+                print_time.tv_usec = now.tv_usec;
        }
 }
 
        }
 }