xfel/progress.c
2021-10-28 09:55:11 +08:00

75 lines
1.6 KiB
C

#include <progress.h>
static double gettime(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + (double)tv.tv_usec / 1000000.0;
}
static const char * format_eta(double remaining)
{
static char result[6] = "";
int seconds = remaining + 0.5;
if(seconds >= 0 && seconds < 6000)
{
snprintf(result, sizeof(result), "%02d:%02d", seconds / 60, seconds % 60);
return result;
}
return "--:--";
}
static char * ssize(char * buf, double size)
{
const char * unit[] = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
int count = 0;
while((size > 1024) && (count < 8))
{
size /= 1024;
count++;
}
sprintf(buf, "%5.3f %s", size, unit[count]);
return buf;
}
void progress_start(struct progress_t * p, uint64_t total)
{
if(p && (total > 0))
{
p->total = total;
p->done = 0;
p->start = gettime();
}
}
void progress_update(struct progress_t * p, uint64_t bytes)
{
char buf1[32], buf2[32];
if(p)
{
p->done += bytes;
double ratio = p->total > 0 ? (double)p->done / (double)p->total : 0.0;
double speed = (double)p->done / (gettime() - p->start);
double eta = speed > 0 ? (p->total - p->done) / speed : 0;
int i, pos = 48 * ratio;
printf("\r%3.0f%% [", ratio * 100);
for(i = 0; i < pos; i++)
putchar('=');
for(i = pos; i < 48; i++)
putchar(' ');
if(p->done < p->total)
printf("] %s/s, ETA %s \r", ssize(buf1, speed), format_eta(eta));
else
printf("] %s, %s/s \r", ssize(buf1, p->done), ssize(buf2, speed));
fflush(stdout);
}
}
void progress_stop(struct progress_t * p)
{
if(p)
printf("\r\n");
}