| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Schedule::Activity::Attribute; |
|
2
|
|
|
|
|
|
|
|
|
3
|
4
|
|
|
4
|
|
6214
|
use strict; |
|
|
4
|
|
|
|
|
9
|
|
|
|
4
|
|
|
|
|
154
|
|
|
4
|
4
|
|
|
4
|
|
23
|
use warnings; |
|
|
4
|
|
|
|
|
11
|
|
|
|
4
|
|
|
|
|
220
|
|
|
5
|
4
|
|
|
4
|
|
647
|
use Ref::Util qw/is_hashref is_ref/; |
|
|
4
|
|
|
|
|
2923
|
|
|
|
4
|
|
|
|
|
10426
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION='0.3.0'; |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
my %types=( |
|
10
|
|
|
|
|
|
|
int=>{ |
|
11
|
|
|
|
|
|
|
change =>\&_changeInt, |
|
12
|
|
|
|
|
|
|
average=>\&_avgInt, |
|
13
|
|
|
|
|
|
|
changes=>{map {$_=>undef} qw/type value set incr decr tm note/}, |
|
14
|
|
|
|
|
|
|
}, |
|
15
|
|
|
|
|
|
|
bool=>{ |
|
16
|
|
|
|
|
|
|
change =>\&_changeBool, |
|
17
|
|
|
|
|
|
|
average=>\&_avgBool, |
|
18
|
|
|
|
|
|
|
changes=>{map {$_=>undef} qw/type value set tm note/}, |
|
19
|
|
|
|
|
|
|
}, |
|
20
|
|
|
|
|
|
|
); |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
sub new { |
|
23
|
129
|
|
|
129
|
0
|
535979
|
my ($ref,%opt)=@_; |
|
24
|
129
|
|
33
|
|
|
599
|
my $class=is_ref($ref)||$ref; |
|
25
|
129
|
|
100
|
|
|
897
|
my ($tm,$y)=($opt{tm}//0,$opt{value}//0); |
|
|
|
|
100
|
|
|
|
|
|
26
|
|
|
|
|
|
|
my %self=( |
|
27
|
129
|
|
100
|
|
|
1438
|
type =>$opt{type}//'int', |
|
28
|
|
|
|
|
|
|
value=>$y, |
|
29
|
|
|
|
|
|
|
log =>{$tm=>$y}, |
|
30
|
|
|
|
|
|
|
aog =>{$tm=>$y}, |
|
31
|
|
|
|
|
|
|
tmmax=>$tm, |
|
32
|
|
|
|
|
|
|
avg =>$y, |
|
33
|
|
|
|
|
|
|
tmsum=>0, |
|
34
|
|
|
|
|
|
|
); |
|
35
|
129
|
100
|
|
|
|
441
|
if(!defined($types{$self{type}})) { die "Attribute invalid type: $self{type}" } |
|
|
1
|
|
|
|
|
20
|
|
|
36
|
128
|
|
|
|
|
608
|
return bless(\%self,$class); |
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub validateConfig { |
|
40
|
114
|
|
|
114
|
1
|
285
|
my ($self,%opt)=@_; |
|
41
|
114
|
|
|
|
|
302
|
my $C=$types{$$self{type}}{changes}; |
|
42
|
114
|
|
|
|
|
285
|
my @errors=grep {!exists($$C{$_})} keys %opt; |
|
|
137
|
|
|
|
|
353
|
|
|
43
|
114
|
50
|
|
|
|
295
|
if(@errors) { return "Invalid attribute options/commands: ".join(' ',@errors) } |
|
|
0
|
|
|
|
|
0
|
|
|
44
|
114
|
|
|
|
|
429
|
return; |
|
45
|
|
|
|
|
|
|
} |
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
sub log { |
|
48
|
856421
|
|
|
856421
|
1
|
1605056
|
my ($self,$tm)=@_; |
|
49
|
856421
|
50
|
33
|
|
|
3121799
|
if(defined($tm)&&($tm>=$$self{tmmax})) { $$self{log}{$tm}=$$self{value}; $$self{aog}{$tm}=$$self{avg}//$$self{value}; $$self{tmmax}=$tm } |
|
|
856421
|
|
100
|
|
|
2040617
|
|
|
|
856421
|
|
|
|
|
2408109
|
|
|
|
856421
|
|
|
|
|
1504983
|
|
|
50
|
|
|
|
|
|
|
# historic entry is not currently supported |
|
51
|
856421
|
|
|
|
|
1500354
|
return $self; |
|
52
|
|
|
|
|
|
|
} |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub change { |
|
55
|
720577
|
|
|
720577
|
1
|
1806944
|
my ($self,%opt)=@_; |
|
56
|
720577
|
|
66
|
|
|
1756147
|
my $tm=$opt{tm}//$$self{tmmax}; |
|
57
|
720577
|
100
|
|
|
|
1633269
|
if($tm<$$self{tmmax}) { return $self } # historic entry is not currently supported |
|
|
14268
|
|
|
|
|
37830
|
|
|
58
|
|
|
|
|
|
|
# |
|
59
|
706309
|
|
|
|
|
1332511
|
&{$types{$$self{type}}{change}}($self,%opt); |
|
|
706309
|
|
|
|
|
2211605
|
|
|
60
|
706309
|
|
|
|
|
2025752
|
$self->log($tm); # updates tmmax |
|
61
|
706309
|
50
|
|
|
|
1489099
|
if(!defined($$self{avg})) { $self->average() } |
|
|
0
|
|
|
|
|
0
|
|
|
62
|
706309
|
|
|
|
|
1804601
|
return $self; |
|
63
|
|
|
|
|
|
|
} |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub report { |
|
66
|
35770
|
|
|
35770
|
1
|
65572
|
my ($self)=@_; |
|
67
|
|
|
|
|
|
|
return ( |
|
68
|
|
|
|
|
|
|
y =>$$self{value}, |
|
69
|
35770
|
|
|
|
|
98644
|
xy =>[$self->_xy()], |
|
70
|
|
|
|
|
|
|
avg=>$self->average(), |
|
71
|
|
|
|
|
|
|
); |
|
72
|
|
|
|
|
|
|
} |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
sub value { |
|
75
|
22
|
|
|
22
|
1
|
21171
|
my ($self)=@_; |
|
76
|
22
|
100
|
|
|
|
81
|
if($$self{type} eq 'int') { return 0+$$self{value} } |
|
|
16
|
|
|
|
|
138
|
|
|
77
|
6
|
50
|
|
|
|
26
|
if($$self{type} eq 'bool') { return !!$$self{value} } |
|
|
6
|
|
|
|
|
37
|
|
|
78
|
|
|
|
|
|
|
} |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
sub average { |
|
81
|
185894
|
|
|
185894
|
1
|
342084
|
my ($self)=@_; |
|
82
|
185894
|
100
|
|
|
|
408940
|
if(defined($$self{avg})) { return $$self{avg} } |
|
|
35782
|
|
|
|
|
170319
|
|
|
83
|
150112
|
|
|
|
|
267018
|
($$self{avg},$$self{tmsum})=&{$types{$$self{type}}{average}}($$self{log}); |
|
|
150112
|
|
|
|
|
365603
|
|
|
84
|
150112
|
|
|
|
|
295838
|
return $$self{avg}; |
|
85
|
|
|
|
|
|
|
} |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
sub reset { |
|
88
|
2840
|
|
|
2840
|
0
|
6004
|
my ($self)=@_; |
|
89
|
2840
|
|
|
|
|
5409
|
foreach my $tm (sort {$a<=>$b} keys %{$$self{log}}) { $$self{tmmax}=$tm; $$self{value}=$$self{log}{$tm}; last } |
|
|
1
|
|
|
|
|
6
|
|
|
|
2840
|
|
|
|
|
9094
|
|
|
|
2840
|
|
|
|
|
7296
|
|
|
|
2840
|
|
|
|
|
6250
|
|
|
|
2840
|
|
|
|
|
6804
|
|
|
90
|
2840
|
|
|
|
|
9161
|
my ($y,$tm)=@$self{qw/value tmmax/}; |
|
91
|
2840
|
|
|
|
|
5258
|
%{$$self{log}}=($tm=>$y); |
|
|
2840
|
|
|
|
|
8999
|
|
|
92
|
2840
|
|
|
|
|
5386
|
%{$$self{aog}}=($tm=>$y); |
|
|
2840
|
|
|
|
|
6437
|
|
|
93
|
2840
|
|
|
|
|
5599
|
$$self{avg}=$y; |
|
94
|
2840
|
|
|
|
|
5774
|
$$self{tmsum}=0; |
|
95
|
2840
|
|
|
|
|
8182
|
return $self; |
|
96
|
|
|
|
|
|
|
} |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub dump { |
|
99
|
385337
|
|
|
385337
|
1
|
694014
|
my ($self)=@_; |
|
100
|
|
|
|
|
|
|
my %res=( |
|
101
|
385337
|
|
|
|
|
1497753
|
log=>{ %{$$self{log}} }, |
|
102
|
385337
|
|
|
|
|
1570225
|
aog=>{ %{$$self{aog}} }, |
|
103
|
385337
|
|
|
|
|
607320
|
(map {$_=>$$self{$_}} qw/type value tmmax avg tmsum/), |
|
|
1926685
|
|
|
|
|
4948665
|
|
|
104
|
|
|
|
|
|
|
); |
|
105
|
385337
|
|
|
|
|
2269539
|
return %res; |
|
106
|
|
|
|
|
|
|
} |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub restore { |
|
109
|
352446
|
|
|
352446
|
1
|
1378519
|
my ($ref,%opt)=@_; |
|
110
|
352446
|
100
|
|
|
|
807320
|
if(is_hashref($ref)) { |
|
111
|
1
|
|
|
|
|
5
|
foreach my $k (keys %opt) { $$ref{$k}=$opt{$k} } |
|
|
7
|
|
|
|
|
18
|
|
|
112
|
1
|
|
|
|
|
5
|
return $ref; |
|
113
|
|
|
|
|
|
|
} |
|
114
|
352445
|
|
50
|
|
|
826524
|
my $y=$opt{value}//0; |
|
115
|
|
|
|
|
|
|
my %self=( |
|
116
|
|
|
|
|
|
|
type =>$opt{type}//'int', |
|
117
|
|
|
|
|
|
|
value=>$y, |
|
118
|
|
|
|
|
|
|
log =>$opt{log}//{}, |
|
119
|
|
|
|
|
|
|
aog =>$opt{aog}//{}, |
|
120
|
|
|
|
|
|
|
tmmax=>$opt{tmmax}//0, |
|
121
|
|
|
|
|
|
|
avg =>$opt{avg}//$y, |
|
122
|
352445
|
|
50
|
|
|
2933116
|
tmsum=>$opt{tmsum}//0, |
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
123
|
|
|
|
|
|
|
); |
|
124
|
352445
|
|
|
|
|
2252561
|
return bless(\%self,$ref); |
|
125
|
|
|
|
|
|
|
} |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
sub _xy { |
|
128
|
35770
|
|
|
35770
|
|
66480
|
my ($self)=@_; |
|
129
|
35770
|
|
|
|
|
61237
|
return map {[$_,$$self{log}{$_},$$self{aog}{$_}]} sort {$a<=>$b} keys %{$$self{log}}; |
|
|
221923
|
|
|
|
|
763348
|
|
|
|
407390
|
|
|
|
|
724515
|
|
|
|
35770
|
|
|
|
|
186709
|
|
|
130
|
|
|
|
|
|
|
} |
|
131
|
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
# set=>value |
|
133
|
|
|
|
|
|
|
# incr=>value |
|
134
|
|
|
|
|
|
|
# decr=>value |
|
135
|
|
|
|
|
|
|
# tm=>tm # optional, will create a log entry |
|
136
|
|
|
|
|
|
|
sub _changeInt { |
|
137
|
706239
|
|
|
706239
|
|
1550826
|
my ($self,%opt)=@_; |
|
138
|
706239
|
|
|
|
|
1272880
|
my $ya=$$self{value}; |
|
139
|
706239
|
100
|
|
|
|
1566668
|
if(defined($opt{set})) { $$self{value}=$opt{set} } |
|
|
75036
|
|
|
|
|
140317
|
|
|
140
|
706239
|
100
|
|
|
|
1694801
|
if($opt{incr}) { $$self{value}+=$opt{incr} } |
|
|
193432
|
|
|
|
|
387381
|
|
|
141
|
706239
|
100
|
|
|
|
1522405
|
if($opt{decr}) { $$self{value}-=$opt{decr} } |
|
|
1
|
|
|
|
|
4
|
|
|
142
|
706239
|
100
|
|
|
|
1476164
|
if($opt{_log}) { } |
|
143
|
|
|
|
|
|
|
# |
|
144
|
706239
|
|
66
|
|
|
1869271
|
my $dt=($opt{tm}//$$self{tmmax})-$$self{tmmax}; |
|
145
|
706239
|
100
|
|
|
|
1908270
|
if($dt==0) { $$self{avg}=$$self{tmsum}=undef; $self->log($$self{tmmax})->average() } |
|
|
150094
|
50
|
|
|
|
321490
|
|
|
|
150094
|
|
|
|
|
397555
|
|
|
146
|
|
|
|
|
|
|
elsif(defined($$self{avg})) { |
|
147
|
556145
|
|
|
|
|
1963394
|
$$self{avg}=$$self{avg}*($$self{tmsum}/($$self{tmsum}+$dt))+0.5*($ya+$$self{value})*($dt/($$self{tmsum}+$dt)); |
|
148
|
556145
|
|
|
|
|
932659
|
$$self{tmsum}+=$dt; |
|
149
|
|
|
|
|
|
|
} |
|
150
|
0
|
|
|
|
|
0
|
else { $$self{avg}=0.5*($ya+$$self{value}); $$self{tmsum}+=$dt } |
|
|
0
|
|
|
|
|
0
|
|
|
151
|
706239
|
|
|
|
|
1526036
|
return $self; |
|
152
|
|
|
|
|
|
|
} |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# set=>value |
|
155
|
|
|
|
|
|
|
# tm=>tm # optional, will create a log entry |
|
156
|
|
|
|
|
|
|
sub _changeBool { |
|
157
|
70
|
|
|
70
|
|
135
|
my ($self,%opt)=@_; |
|
158
|
70
|
|
|
|
|
105
|
my $ya=$$self{value}; |
|
159
|
70
|
100
|
|
|
|
178
|
if(defined($opt{set})) { $$self{value}=$opt{set} } |
|
|
44
|
|
|
|
|
96
|
|
|
160
|
70
|
100
|
|
|
|
193
|
if($opt{_log}) { } |
|
161
|
|
|
|
|
|
|
# |
|
162
|
70
|
|
66
|
|
|
151
|
my $dt=($opt{tm}//$$self{tmmax})-$$self{tmmax}; |
|
163
|
70
|
100
|
|
|
|
148
|
if($dt==0) { $$self{avg}=$$self{tmsum}=undef; $self->log($$self{tmmax})->average() } |
|
|
18
|
50
|
|
|
|
59
|
|
|
|
18
|
|
|
|
|
39
|
|
|
164
|
|
|
|
|
|
|
elsif(defined($$self{avg})) { |
|
165
|
52
|
|
|
|
|
150
|
$$self{avg}=$$self{avg}*$$self{tmsum}/($$self{tmsum}+$dt)+$dt*$ya/($$self{tmsum}+$dt); |
|
166
|
52
|
|
|
|
|
80
|
$$self{tmsum}+=$dt; |
|
167
|
|
|
|
|
|
|
} |
|
168
|
0
|
|
|
|
|
0
|
else { $$self{avg}=$ya; $$self{tmsum}+=$dt } |
|
|
0
|
|
|
|
|
0
|
|
|
169
|
70
|
|
|
|
|
124
|
return $self; |
|
170
|
|
|
|
|
|
|
} |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
sub _avgInt { |
|
173
|
150094
|
|
|
150094
|
|
267941
|
my ($log)=@_; |
|
174
|
150094
|
|
|
|
|
328451
|
my ($avg,$weight,$lasttm,$lasty)=(0,0); |
|
175
|
150094
|
|
|
|
|
432017
|
foreach my $tm (sort {$a<=>$b} keys(%$log)) { |
|
|
29462
|
|
|
|
|
53381
|
|
|
176
|
163632
|
100
|
|
|
|
342798
|
if(!defined($lasttm)) { ($lasttm,$lasty,$avg,$weight)=($tm,$$log{$tm},$$log{$tm},0); next } |
|
|
150094
|
|
|
|
|
385546
|
|
|
|
150094
|
|
|
|
|
312357
|
|
|
177
|
13538
|
|
|
|
|
19691
|
my $dt=$tm-$lasttm; |
|
178
|
13538
|
|
|
|
|
34418
|
$avg=$weight/($weight+$dt)*$avg+0.5*$dt/($weight+$dt)*($lasty+$$log{$tm}); |
|
179
|
13538
|
|
|
|
|
20009
|
$weight+=$dt; |
|
180
|
13538
|
|
|
|
|
20241
|
$lasttm=$tm; |
|
181
|
13538
|
|
|
|
|
24433
|
$lasty=$$log{$tm}; |
|
182
|
|
|
|
|
|
|
} |
|
183
|
150094
|
|
|
|
|
483060
|
return ($avg,$weight); |
|
184
|
|
|
|
|
|
|
} |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub _avgBool { |
|
187
|
18
|
|
|
18
|
|
37
|
my ($log)=@_; |
|
188
|
18
|
|
|
|
|
32
|
my ($sum,$weight,$lasttm,$lasty)=(0,0); |
|
189
|
18
|
|
|
|
|
50
|
foreach my $tm (sort {$a<=>$b} keys(%$log)) { |
|
|
30
|
|
|
|
|
52
|
|
|
190
|
38
|
100
|
|
|
|
76
|
if(!defined($lasttm)) { ($lasttm,$lasty,$sum,$weight)=($tm,$$log{$tm},$$log{$tm},0); next } |
|
|
18
|
|
|
|
|
39
|
|
|
|
18
|
|
|
|
|
37
|
|
|
191
|
20
|
|
|
|
|
29
|
my $dt=$tm-$lasttm; |
|
192
|
20
|
|
|
|
|
30
|
$sum+=$lasty*($tm-$lasttm); |
|
193
|
20
|
|
|
|
|
26
|
$weight+=$dt; |
|
194
|
20
|
|
|
|
|
26
|
$lasttm=$tm; |
|
195
|
20
|
|
|
|
|
31
|
$lasty=$$log{$tm}; |
|
196
|
|
|
|
|
|
|
} |
|
197
|
18
|
100
|
|
|
|
40
|
if($weight==0) { return ($sum,$weight) } |
|
|
10
|
|
|
|
|
24
|
|
|
198
|
8
|
|
|
|
|
21
|
return ($sum/$weight,$weight); |
|
199
|
|
|
|
|
|
|
} |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
1; |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
__END__ |