-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprogress.d
129 lines (103 loc) · 2.62 KB
/
progress.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
module progress;
import std.stdio;
import std.string;
import std.datetime;
import std.algorithm : sort;
import globals;
__gshared SpeedRate speedrate;
auto renderprogress = &progress_console;
class SpeedRate {
this() {
sw.start();
lastx = 0;
}
struct sample {
double x = 0;
uint msecs = 0;
@property double xpersec() {
return x * 1000 / (msecs==0? 1:msecs);
}
}
static immutable uint nsamples = 21;
sample[nsamples] samples;
sample total;
StopWatch sw;
uint pos;
double lastx = 0;
void addcumusample(double x) {
auto diffx = x - lastx;
++pos;
pos %= nsamples;
auto tmpx = samples[pos].x;
auto tmpmsecs = samples[pos].msecs;
uint msecs = cast(uint)sw.peek().msecs;
samples[pos].x = diffx;
samples[pos].msecs = msecs;
total.x += diffx - tmpx;
total.msecs += msecs - tmpmsecs;
//if (getxpersec() < 1) writefln("%.2f %.2f", total.x, total.msecs);
lastx = x;
restart();
}
double getavg() { return total.xpersec; }
double get1xpersec() { return samples[pos].xpersec; }
double getmedian() {
auto c = samples.dup;
sort!("a.xpersec < b.xpersec")(c);
//ignore empty
int i=0;
for (i=0; i<nsamples && c[i].msecs==0 ; i++) {}
i%=nsamples;
auto a = c[i..$];
//writefln("%d %s ", i, c[i..$]);
return a[a.length/2].xpersec;
}
double getharmavg() {
int count=0; double h=0;
foreach(s; samples) {
if(s.msecs==0) continue;
++count;
h += 1/s.xpersec;
//writefln("%d %s %.2f ", count, s.xpersec, h);
}
return (cast(double)count)/h;
}
long peekmsecs() { return sw.peek().msecs; }
void restart() {
sw.stop();
sw.reset();
sw.start();
}
}
void progress_console(double cur, double total, string units, string text="") {
static ulong lastline;
if (options.noprogressbar)
return;
synchronized {
if (speedrate.peekmsecs() >= 1000)
speedrate.addcumusample(cur);
}
auto rate = speedrate.getmedian();
auto timeremain = cast(uint)((total-cur) / rate);
auto sec = timeremain % 60;
auto min = (timeremain/60) % 60;
auto hr = (timeremain/3600);
double percent = cur*100/total;
string output=format(" %.0f%% %.1f %s/sec %d:%02d:%02d %.0f/%.0f %s %s", percent, rate, units, hr,min,sec, cur, total, units, text);
string line;
if (lastline > output.length)
line = output ~ format("%*s\r", lastline - output.length, " ");
else
line = output ~ "\r";
write(line);
lastline=output.length;
stdout.flush();
}
void progress_json(double cur, double total, string units, string text="") {
if (options.noprogressbar)
return;
if (speedrate.peekmsecs() < 500 && cur!=total) return;
speedrate.restart();
writefln(`{ "progress":%.2f }`, cur);
stdout.flush();
}