added iterator funcions for hash and rulelist
[k8jam.git] / src / progress.c
blobe7b4d3c9e0297fc5ebbc72639e092e68df092cf0
1 #include <stdlib.h>
2 #include <string.h>
3 #include <time.h>
5 #include "jam.h"
6 #include "lists.h"
7 #include "parse.h"
8 #include "rules.h"
9 #include "newstr.h"
10 #include "hash.h"
11 #include "variable.h"
12 #include "search.h"
14 #include "progress.h"
17 #define PROGRESS_WINDOW (10)
20 typedef struct {
21 time_t when;
22 int completed;
23 } TIMESTAMP;
26 struct _PROGRESS {
27 int total;
28 int stampcount;
29 TIMESTAMP stamps[PROGRESS_WINDOW];
33 static double getTimeDelta (void) {
34 static double res = 10.0;
35 static int checked = 0;
36 if (!checked) {
37 LIST *var = var_get("K8JAM-PROGRESS-TIME-DELTA"); /*FIXME: a perfectly idiotic name*/
38 if (var) {
39 TARGET *t = bindtarget(var->string);
40 pushsettings(t->settings);
41 t->boundname = search(t->name, &t->time);
42 popsettings(t->settings);
43 if (t->boundname) {
44 res = atof(t->boundname);
45 if (res < 0.0) res = 0.0;
47 checked = 1;
50 return res;
54 #define LAST_STAMP(p) ((p)->stamps[(p)->stampcount-1])
55 #define FIRST_STAMP(p) ((p)->stamps[0])
58 PROGRESS *progress_start (int total) {
59 PROGRESS *p = malloc(sizeof(PROGRESS));
60 p->total = total;
61 p->stampcount = 0;
62 progress_update(p, 0);
63 return p;
67 static double progress_estimate (PROGRESS *progress) {
68 int count;
69 int left;
70 double elapsed;
71 double rate;
73 if (progress->stampcount < 2) return 0.0;
74 count = LAST_STAMP(progress).completed-FIRST_STAMP(progress).completed;
75 left = progress->total-LAST_STAMP(progress).completed;
76 elapsed = (double)(LAST_STAMP(progress).when-FIRST_STAMP(progress).when);
77 if (elapsed <= 0.1) elapsed = 0.1;
78 rate = count/elapsed;
79 return left/rate;
83 double progress_update (PROGRESS *progress, int completed) {
84 time_t now;
85 double dd = getTimeDelta();
87 time(&now);
88 /* only return progress every 10 seconds */
89 if (progress->stampcount > 0 && (dd <= 0.00001 || difftime(now, LAST_STAMP(progress).when) < dd)) return 0.0;
90 if (progress->stampcount == PROGRESS_WINDOW) {
91 memmove(progress->stamps, progress->stamps+1, sizeof(progress->stamps[0])*(PROGRESS_WINDOW-1));
92 --progress->stampcount;
94 ++progress->stampcount;
95 LAST_STAMP(progress).completed = completed;
96 LAST_STAMP(progress).when = now;
97 return progress_estimate(progress);