7 #define PROGRESS_WINDOW 10
19 TIMESTAMP stamps
[PROGRESS_WINDOW
];
23 #define LAST_STAMP(p) ((p)->stamps[(p)->stampcount-1])
24 #define FIRST_STAMP(p) ((p)->stamps[0])
27 PROGRESS
*progress_start (int total
) {
28 PROGRESS
*p
= malloc(sizeof(PROGRESS
));
31 progress_update(p
, 0);
36 static double progress_estimate (PROGRESS
*progress
) {
42 if (progress
->stampcount
< 2) return 0.0;
43 count
= LAST_STAMP(progress
).completed
-FIRST_STAMP(progress
).completed
;
44 left
= progress
->total
-LAST_STAMP(progress
).completed
;
45 elapsed
= (double)(LAST_STAMP(progress
).when
-FIRST_STAMP(progress
).when
);
46 if (elapsed
<= 0.1) elapsed
= 0.1;
52 double progress_update (PROGRESS
*progress
, int completed
) {
56 /* only return progress every 10 seconds */
57 if (progress
->stampcount
> 0 && difftime(now
, LAST_STAMP(progress
).when
) < 10.0) return 0.0;
58 if (progress
->stampcount
== PROGRESS_WINDOW
) {
59 memmove(progress
->stamps
, progress
->stamps
+1, sizeof(progress
->stamps
[0])*(PROGRESS_WINDOW
-1));
60 --progress
->stampcount
;
62 ++progress
->stampcount
;
63 LAST_STAMP(progress
).completed
= completed
;
64 LAST_STAMP(progress
).when
= now
;
65 return progress_estimate(progress
);