built-in jambase is packed now
[k8jam.git] / src / progress.c
blobae1b609ff6b1c427474564e8be825e3750dbf8ba
1 #ifndef __NEATCC__
2 #include <stdlib.h>
3 #include <string.h>
4 #include <time.h>
6 #include "jam.h"
7 #include "lists.h"
8 #include "parse.h"
9 #include "rules.h"
10 #include "newstr.h"
11 #include "hash.h"
12 #include "variable.h"
13 #include "search.h"
15 #include "progress.h"
18 #define PROGRESS_WINDOW (10)
21 typedef struct {
22 time_t when;
23 int completed;
24 } TIMESTAMP;
27 struct _PROGRESS {
28 int total;
29 int stampcount;
30 TIMESTAMP stamps[PROGRESS_WINDOW];
34 static double getTimeDelta (void) {
35 static double res = 10.0;
36 static int checked = 0;
38 if (!checked) {
39 LIST *var = var_get("K8JAM-PROGRESS-TIME-DELTA"); /*FIXME: a perfectly idiotic name*/
40 if (var) {
41 TARGET *t = bindtarget(var->string);
42 pushsettings(t->settings);
43 t->boundname = search(t->name, &t->time);
44 popsettings(t->settings);
45 if (t->boundname) {
46 res = atof(t->boundname);
47 if (res < 0.0) res = 0.0;
49 checked = 1;
52 return res;
56 #define LAST_STAMP(p) ((p)->stamps[(p)->stampcount-1])
57 #define FIRST_STAMP(p) ((p)->stamps[0])
60 PROGRESS *progress_start (int total) {
61 PROGRESS *p = malloc(sizeof(PROGRESS));
62 p->total = total;
63 p->stampcount = 0;
64 progress_update(p, 0);
65 return p;
69 static double progress_estimate (PROGRESS *progress) {
70 int count;
71 int left;
72 double elapsed;
73 double rate;
75 if (progress->stampcount < 2) return 0.0;
76 count = LAST_STAMP(progress).completed-FIRST_STAMP(progress).completed;
77 left = progress->total-LAST_STAMP(progress).completed;
78 elapsed = (double)(LAST_STAMP(progress).when-FIRST_STAMP(progress).when);
79 if (elapsed <= 0.1) elapsed = 0.1;
80 rate = count/elapsed;
81 return left/rate;
85 double progress_update (PROGRESS *progress, int completed) {
86 time_t now;
87 double dd = getTimeDelta();
89 time(&now);
90 /* only return progress every 10 seconds */
91 if (progress->stampcount > 0 && (dd <= 0.00001 || difftime(now, LAST_STAMP(progress).when) < dd)) return 0.0;
92 if (progress->stampcount == PROGRESS_WINDOW) {
93 memmove(progress->stamps, progress->stamps+1, sizeof(progress->stamps[0])*(PROGRESS_WINDOW-1));
94 --progress->stampcount;
96 ++progress->stampcount;
97 LAST_STAMP(progress).completed = completed;
98 LAST_STAMP(progress).when = now;
99 return progress_estimate(progress);
101 #endif