line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package AlignDB::Stopwatch; |
2
|
6
|
|
|
6
|
|
193101
|
use Moose; |
|
6
|
|
|
|
|
2133907
|
|
|
6
|
|
|
|
|
39
|
|
3
|
|
|
|
|
|
|
|
4
|
6
|
|
|
6
|
|
36923
|
use Time::Duration; |
|
6
|
|
|
|
|
10234
|
|
|
6
|
|
|
|
|
549
|
|
5
|
6
|
|
|
6
|
|
2771
|
use Data::UUID; |
|
6
|
|
|
|
|
3539
|
|
|
6
|
|
|
|
|
355
|
|
6
|
6
|
|
|
6
|
|
86
|
use File::Spec; |
|
6
|
|
|
|
|
8
|
|
|
6
|
|
|
|
|
126
|
|
7
|
6
|
|
|
6
|
|
3035
|
use YAML::Syck; |
|
6
|
|
|
|
|
9778
|
|
|
6
|
|
|
|
|
5787
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
our $VERSION = '1.1.0'; |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
has program_name => ( is => 'ro', isa => 'Str' ); |
12
|
|
|
|
|
|
|
has program_argv => ( is => 'ro', isa => 'ArrayRef', default => sub { [] } ); |
13
|
|
|
|
|
|
|
has program_conf => ( is => 'ro', isa => 'Object' ); |
14
|
|
|
|
|
|
|
has 'start_time' => ( is => 'rw', isa => 'Value' ); |
15
|
|
|
|
|
|
|
has 'div_char' => ( is => 'rw', isa => 'Str', default => sub {"="}, ); |
16
|
|
|
|
|
|
|
has 'div_length' => ( is => 'rw', isa => 'Int', default => sub {30}, ); |
17
|
|
|
|
|
|
|
has 'min_div_length' => ( is => 'rw', isa => 'Int', default => sub {5} ); |
18
|
|
|
|
|
|
|
has uuid => ( is => 'ro', isa => 'Str' ); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
sub BUILD { |
21
|
5
|
|
|
5
|
0
|
5440
|
my $self = shift; |
22
|
|
|
|
|
|
|
|
23
|
5
|
|
|
|
|
47
|
$self->{start_time} = time; |
24
|
5
|
|
|
|
|
2076
|
$self->{uuid} = Data::UUID->new->create_str; |
25
|
|
|
|
|
|
|
|
26
|
5
|
|
|
|
|
10597
|
return; |
27
|
|
|
|
|
|
|
} |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
#@returns AlignDB::Stopwatch |
30
|
|
|
|
|
|
|
sub record { |
31
|
1
|
|
|
1
|
1
|
13
|
my $self = shift; |
32
|
|
|
|
|
|
|
|
33
|
1
|
|
|
|
|
4
|
$self->{program_name} = $main::0; |
34
|
|
|
|
|
|
|
|
35
|
1
|
|
|
|
|
3
|
$self->{program_argv} = [@main::ARGV]; |
36
|
|
|
|
|
|
|
|
37
|
1
|
|
|
|
|
3
|
return $self; |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
#@returns AlignDB::Stopwatch |
41
|
|
|
|
|
|
|
sub record_conf { |
42
|
1
|
|
|
1
|
1
|
2
|
my $self = shift; |
43
|
1
|
|
|
|
|
2
|
my $conf = shift; |
44
|
|
|
|
|
|
|
|
45
|
1
|
|
|
|
|
3
|
$self->{program_conf} = $conf; |
46
|
|
|
|
|
|
|
|
47
|
1
|
|
|
|
|
2
|
return $self; |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub _divider { |
51
|
6
|
|
|
6
|
|
12
|
my $self = shift; |
52
|
6
|
|
|
|
|
8
|
my $title = shift; |
53
|
|
|
|
|
|
|
|
54
|
6
|
100
|
|
|
|
16
|
my $title_length = $title ? length $title : 0; |
55
|
|
|
|
|
|
|
|
56
|
6
|
|
|
|
|
320
|
my $div_char = $self->div_char; |
57
|
6
|
|
|
|
|
348
|
my $div_length = $self->div_length; |
58
|
6
|
|
|
|
|
360
|
my $min_div_length = $self->min_div_length; |
59
|
|
|
|
|
|
|
|
60
|
6
|
|
|
|
|
13
|
my $divider_str; |
61
|
|
|
|
|
|
|
|
62
|
6
|
100
|
|
|
|
32
|
if ( !$title_length ) { |
|
|
100
|
|
|
|
|
|
63
|
4
|
|
|
|
|
19
|
$divider_str .= $div_char x $div_length; |
64
|
4
|
|
|
|
|
8
|
$divider_str .= "\n"; |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
elsif ( $title_length > $div_length - 2 * $min_div_length ) { |
67
|
1
|
|
|
|
|
5
|
$divider_str .= $div_char x $min_div_length; |
68
|
1
|
|
|
|
|
5
|
$divider_str .= $title; |
69
|
1
|
|
|
|
|
5
|
$divider_str .= $div_char x $min_div_length; |
70
|
1
|
|
|
|
|
3
|
$divider_str .= "\n"; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
else { |
73
|
1
|
|
|
|
|
7
|
my $left_length = int( ( $div_length - $title_length ) / 2 ); |
74
|
1
|
|
|
|
|
17
|
my $right_length = $div_length - $title_length - $left_length; |
75
|
1
|
|
|
|
|
3
|
$divider_str .= $div_char x $left_length; |
76
|
1
|
|
|
|
|
2
|
$divider_str .= $title; |
77
|
1
|
|
|
|
|
1
|
$divider_str .= $div_char x $right_length; |
78
|
1
|
|
|
|
|
2
|
$divider_str .= "\n"; |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
6
|
|
|
|
|
21
|
return $divider_str; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub _prompt { |
85
|
6
|
|
|
6
|
|
5
|
my $self = shift; |
86
|
6
|
|
|
|
|
12
|
return "==> "; |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub _empty_line { |
90
|
16
|
|
|
16
|
|
21
|
my $self = shift; |
91
|
16
|
|
|
|
|
36
|
return "\n"; |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub _time { |
95
|
8
|
|
|
8
|
|
15
|
my $self = shift; |
96
|
8
|
|
|
|
|
14
|
my $title = shift; |
97
|
|
|
|
|
|
|
|
98
|
8
|
|
|
|
|
11
|
my $time_str; |
99
|
|
|
|
|
|
|
|
100
|
8
|
100
|
|
|
|
61
|
if ( !defined $title ) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
101
|
1
|
|
|
|
|
3
|
$time_str .= "Current time: "; |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
elsif ( $title =~ /start/i ) { |
104
|
4
|
|
|
|
|
11
|
$time_str .= "Start at: "; |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
elsif ( $title =~ /end/i ) { |
107
|
2
|
|
|
|
|
9
|
$time_str .= "End at: "; |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
else { |
110
|
1
|
|
|
|
|
3
|
$time_str .= "$title: "; |
111
|
|
|
|
|
|
|
} |
112
|
8
|
|
|
|
|
403
|
$time_str .= scalar localtime; |
113
|
8
|
|
|
|
|
14
|
$time_str .= "\n"; |
114
|
|
|
|
|
|
|
|
115
|
8
|
|
|
|
|
36
|
return $time_str; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
sub _duration { |
119
|
3
|
|
|
3
|
|
7
|
my $self = shift; |
120
|
3
|
|
|
|
|
11
|
return "Runtime " . $self->duration_now . ".\n"; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub _message { |
124
|
8
|
|
|
8
|
|
22
|
my $self = shift; |
125
|
8
|
|
|
|
|
10
|
my $message = shift; |
126
|
|
|
|
|
|
|
|
127
|
8
|
100
|
|
|
|
25
|
$message = '' unless defined $message; |
128
|
|
|
|
|
|
|
|
129
|
8
|
|
|
|
|
36
|
return $message . "\n"; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
sub duration_now { |
133
|
7
|
|
|
7
|
0
|
2001821
|
my $self = shift; |
134
|
7
|
|
|
|
|
579
|
return Time::Duration::duration( time - $self->start_time ); |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub block_message { |
138
|
4
|
|
|
4
|
1
|
2285
|
my $self = shift; |
139
|
4
|
|
|
|
|
6
|
my $message = shift; |
140
|
4
|
|
|
|
|
4
|
my $with_duration = shift; |
141
|
|
|
|
|
|
|
|
142
|
4
|
|
|
|
|
3
|
my $text; |
143
|
4
|
|
|
|
|
10
|
$text .= $self->_empty_line; |
144
|
4
|
|
|
|
|
9
|
$text .= $self->_prompt; |
145
|
4
|
|
|
|
|
6
|
$text .= $self->_message($message); |
146
|
4
|
100
|
|
|
|
10
|
if ($with_duration) { |
147
|
1
|
|
|
|
|
2
|
$text .= $self->_prompt; |
148
|
1
|
|
|
|
|
3
|
$text .= $self->_duration; |
149
|
|
|
|
|
|
|
} |
150
|
4
|
|
|
|
|
13
|
$text .= $self->_empty_line; |
151
|
|
|
|
|
|
|
|
152
|
4
|
|
|
|
|
97
|
print $text; |
153
|
|
|
|
|
|
|
|
154
|
4
|
|
|
|
|
17
|
return; |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
sub start_message { |
158
|
4
|
|
|
4
|
1
|
5676
|
my $self = shift; |
159
|
4
|
|
|
|
|
14
|
my $message = shift; |
160
|
4
|
|
|
|
|
9
|
my $embed_in_divider = shift; |
161
|
|
|
|
|
|
|
|
162
|
4
|
|
|
|
|
33
|
my $text; |
163
|
4
|
100
|
|
|
|
19
|
if ( defined $message ) { |
164
|
3
|
100
|
|
|
|
13
|
if ( defined $embed_in_divider ) { |
165
|
2
|
|
|
|
|
24
|
$text .= $self->_divider($message); |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
else { |
168
|
1
|
|
|
|
|
19
|
$text .= $self->_divider; |
169
|
1
|
|
|
|
|
6
|
$text .= $self->_message($message); |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
else { |
173
|
1
|
|
|
|
|
5
|
$text .= $self->_divider; |
174
|
|
|
|
|
|
|
} |
175
|
4
|
|
|
|
|
16
|
$text .= $self->_time("start"); |
176
|
4
|
|
|
|
|
27
|
$text .= $self->_empty_line; |
177
|
|
|
|
|
|
|
|
178
|
4
|
|
|
|
|
300
|
print $text; |
179
|
|
|
|
|
|
|
|
180
|
4
|
|
|
|
|
24
|
return; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
sub end_message { |
184
|
2
|
|
|
2
|
1
|
2079
|
my $self = shift; |
185
|
2
|
|
|
|
|
8
|
my $message = shift; |
186
|
|
|
|
|
|
|
|
187
|
2
|
|
|
|
|
4
|
my $text; |
188
|
2
|
|
|
|
|
12
|
$text .= $self->_empty_line; |
189
|
2
|
100
|
|
|
|
15
|
if ( defined $message ) { |
190
|
1
|
|
|
|
|
7
|
$text .= $self->_message($message); |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
} |
193
|
2
|
|
|
|
|
9
|
$text .= $self->_time("end"); |
194
|
2
|
|
|
|
|
13
|
$text .= $self->_duration; |
195
|
2
|
|
|
|
|
43
|
$text .= $self->_divider; |
196
|
|
|
|
|
|
|
|
197
|
2
|
|
|
|
|
114
|
print $text; |
198
|
|
|
|
|
|
|
|
199
|
2
|
|
|
|
|
19
|
return; |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub cmd_line { |
203
|
1
|
|
|
1
|
0
|
2
|
my $self = shift; |
204
|
1
|
|
|
|
|
38
|
return join( ' ', $self->program_name, @{ $self->program_argv } ); |
|
1
|
|
|
|
|
29
|
|
205
|
|
|
|
|
|
|
} |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
sub init_config { |
208
|
1
|
|
|
1
|
0
|
1
|
my $self = shift; |
209
|
1
|
|
|
|
|
36
|
return YAML::Syck::Dump $self->program_conf; |
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
sub operation { |
213
|
1
|
|
|
1
|
0
|
6
|
my $self = shift; |
214
|
1
|
|
|
|
|
39
|
my ( undef, undef, $filename ) = File::Spec->splitpath( $self->program_name ); |
215
|
1
|
|
|
|
|
6
|
return $filename; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
1; |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
__END__ |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
=head1 NAME |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
AlignDB::Stopwatch - Record running time and print standard messages |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
=head1 SYNOPSIS |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
use AlignDB::Stopwatch; |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
# record command line |
231
|
|
|
|
|
|
|
my $stopwatch = AlignDB::Stopwatch->new->record; |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
# record config |
234
|
|
|
|
|
|
|
$stopwatch->record_conf($opt); |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
$stopwatch->start_message("Doing really bad things..."); |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
$stopwatch->end_message; |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
=head2 program_name |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
program name |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
=head2 program_argv |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
program command line options |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
=head2 program_conf |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
program configurations |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
=head2 start_time |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
start time |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
=head2 div_char |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
Divider char used in output messages, default is [=] |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
=head2 div_length |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
Length of divider char, default is [30] |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=head2 min_div_length |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
minimal single-side divider length, default is [5] |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=head2 uuid |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
Use Data::UUID to generate a UUID that prevent inserting meta info more than |
273
|
|
|
|
|
|
|
one time on multithreads mode |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
=head1 METHODS |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
=head2 record |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
Record $main::0 to program_name and [@main::ARGV] to program_argv. |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
Getopt::Long would manipulate @ARGV. |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
my $stopwatch = AlignDB::Stopwatch->new->record; |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
=head2 record_conf |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
Record a hashref or object to program_conf. |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
$stopwatch->record_conf( $opt ); |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
=head2 block_message |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
Print a blocked message |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
$stopwatch->block_message( $message, $with_duration ); |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=head2 start_message |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
Print a starting message |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
$stopwatch->start_message( $message, $embed_in_divider ); |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
=head2 end_message |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
Print a ending message |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
$stopwatch->end_message( $message ); |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
=head1 AUTHOR |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
Qiang Wang <wang-q@outlook.com> |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
This software is copyright (c) 2008- by Qiang Wang. |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
318
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=cut |