diff options
author | Martin Pool <mbp@samba.org> | 2002-04-08 04:10:20 +0000 |
---|---|---|
committer | Martin Pool <mbp@samba.org> | 2002-04-08 04:10:20 +0000 |
commit | b35d0d8e9ae9c5407c9f781b545f8a66b9caa9d0 (patch) | |
tree | ca00ceac1d12f7d7494ab5120e508e99db26b2cc /progress.c | |
parent | c948e309f27c3edaef8a5a4dfc04e0da98944c97 (diff) | |
download | android_external_rsync-b35d0d8e9ae9c5407c9f781b545f8a66b9caa9d0.tar.gz android_external_rsync-b35d0d8e9ae9c5407c9f781b545f8a66b9caa9d0.tar.bz2 android_external_rsync-b35d0d8e9ae9c5407c9f781b545f8a66b9caa9d0.zip |
Split code out into separate files and remove some global variables to
reduce symbol dependencies between files and therefore make it easier
to write unit tests. The diff is large, but the actual code changes
are pretty small.
Diffstat (limited to 'progress.c')
-rw-r--r-- | progress.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/progress.c b/progress.c new file mode 100644 index 00000000..004b5d1b --- /dev/null +++ b/progress.c @@ -0,0 +1,96 @@ +#include "rsync.h" + +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 ofs Current position in file + * @param size Total size of file + * @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 = (ofs == size) ? 100 : (int)((100.0*ofs)/size); + unsigned long diff = msdiff(&start_time, now); + double rate = diff ? (double) (ofs-start_ofs) * 1000.0 / diff / 1024.0 : 0; + const char *units; + /* If we've finished transferring this file, show the time taken; + * otherwise show expected time to complete. That's kind of + * inconsistent, but people can probably cope. Hopefully we'll + * get more consistent and complete progress reporting soon. -- + * mbp */ + double remain = is_last + ? (double) diff / 1000.0 + : rate ? (double) (size-ofs) / rate / 1000.0 : 0.0; + int remain_h, remain_m, remain_s; + + 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"; + } + + remain_s = (int) remain % 60; + remain_m = (int) (remain / 60.0) % 60; + remain_h = (int) (remain / 3600.0); + + rprintf(FINFO, "%12.0f %3d%% %7.2f%s %4d:%02d:%02d%s", + (double) ofs, pct, rate, units, + remain_h, remain_m, remain_s, + is_last ? "\n" : "\r"); +} + +void end_progress(OFF_T size) +{ + extern int do_progress, am_server; + + if (do_progress && !am_server) { + struct timeval now; + gettimeofday(&now, NULL); + rprint_progress(size, size, &now, True); + } + 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; + 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; + } +} |