← Index
NYTProf Performance Profile   « line view »
For /home/ss5/perl5/perlbrew/perls/perl-5.22.0/bin/benchmarkanything-storage
  Run on Mon Jan 29 16:55:34 2018
Reported on Mon Jan 29 16:57:06 2018

Filename/home/ss5/perl5/perlbrew/perls/perl-5.22.0/lib/site_perl/5.22.0/BenchmarkAnything/Storage/Frontend/Lib.pm
StatementsExecuted 2062 statements in 10.3ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1119.88ms58.9msBenchmarkAnything::Storage::Frontend::Lib::::connectBenchmarkAnything::Storage::Frontend::Lib::connect
1119.64ms53.0sBenchmarkAnything::Storage::Frontend::Lib::::process_raw_result_queueBenchmarkAnything::Storage::Frontend::Lib::process_raw_result_queue
111699µs996µsBenchmarkAnything::Storage::Frontend::Lib::::BEGIN@10BenchmarkAnything::Storage::Frontend::Lib::BEGIN@10
111420µs329msBenchmarkAnything::Storage::Frontend::Lib::::BEGIN@280BenchmarkAnything::Storage::Frontend::Lib::BEGIN@280
111254µs97.0msBenchmarkAnything::Storage::Frontend::Lib::::newBenchmarkAnything::Storage::Frontend::Lib::new
11119µs26µsBenchmarkAnything::Storage::Frontend::Lib::::disconnectBenchmarkAnything::Storage::Frontend::Lib::disconnect
11115µs15µsmain::::BEGIN@1.22 main::BEGIN@1.22
11112µs34.3msBenchmarkAnything::Storage::Frontend::Lib::::gcBenchmarkAnything::Storage::Frontend::Lib::gc
1119µs26µsBenchmarkAnything::Storage::Frontend::Lib::::BEGIN@27BenchmarkAnything::Storage::Frontend::Lib::BEGIN@27
1118µs16µsBenchmarkAnything::Storage::Frontend::Lib::::BEGIN@275BenchmarkAnything::Storage::Frontend::Lib::BEGIN@275
1117µs16µsBenchmarkAnything::Storage::Frontend::Lib::::BEGIN@189BenchmarkAnything::Storage::Frontend::Lib::BEGIN@189
1116µs9µsmain::::BEGIN@2 main::BEGIN@2
1116µs12µsBenchmarkAnything::Storage::Frontend::Lib::::BEGIN@36BenchmarkAnything::Storage::Frontend::Lib::BEGIN@36
1116µs11µsBenchmarkAnything::Storage::Frontend::Lib::::BEGIN@51BenchmarkAnything::Storage::Frontend::Lib::BEGIN@51
1116µs11µsBenchmarkAnything::Storage::Frontend::Lib::::BEGIN@66BenchmarkAnything::Storage::Frontend::Lib::BEGIN@66
1115µs15µsmain::::BEGIN@3 main::BEGIN@3
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::_are_you_sureBenchmarkAnything::Storage::Frontend::Lib::_are_you_sure
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::_default_additional_keysBenchmarkAnything::Storage::Frontend::Lib::_default_additional_keys
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::_format_flatBenchmarkAnything::Storage::Frontend::Lib::_format_flat
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::_format_flat_inner_arrayBenchmarkAnything::Storage::Frontend::Lib::_format_flat_inner_array
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::_format_flat_inner_hashBenchmarkAnything::Storage::Frontend::Lib::_format_flat_inner_hash
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::_format_flat_inner_scalarBenchmarkAnything::Storage::Frontend::Lib::_format_flat_inner_scalar
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::_format_flat_outerBenchmarkAnything::Storage::Frontend::Lib::_format_flat_outer
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::_get_additional_key_idBenchmarkAnything::Storage::Frontend::Lib::_get_additional_key_id
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::_get_base_urlBenchmarkAnything::Storage::Frontend::Lib::_get_base_url
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::_get_benchmark_operatorsBenchmarkAnything::Storage::Frontend::Lib::_get_benchmark_operators
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::_get_user_agentBenchmarkAnything::Storage::Frontend::Lib::_get_user_agent
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::_output_formatBenchmarkAnything::Storage::Frontend::Lib::_output_format
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::addBenchmarkAnything::Storage::Frontend::Lib::add
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::createdbBenchmarkAnything::Storage::Frontend::Lib::createdb
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::getpointBenchmarkAnything::Storage::Frontend::Lib::getpoint
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::init_search_engineBenchmarkAnything::Storage::Frontend::Lib::init_search_engine
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::init_workdirBenchmarkAnything::Storage::Frontend::Lib::init_workdir
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::listkeysBenchmarkAnything::Storage::Frontend::Lib::listkeys
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::listnamesBenchmarkAnything::Storage::Frontend::Lib::listnames
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::searchBenchmarkAnything::Storage::Frontend::Lib::search
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::statsBenchmarkAnything::Storage::Frontend::Lib::stats
0000s0sBenchmarkAnything::Storage::Frontend::Lib::::sync_search_engineBenchmarkAnything::Storage::Frontend::Lib::sync_search_engine
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1231µs115µs
# spent 15µs within main::BEGIN@1.22 which was called: # once (15µs+0s) by main::_connect at line 1
use 5.008;
# spent 15µs making 1 call to main::BEGIN@1.22
2215µs212µs
# spent 9µs (6+3) within main::BEGIN@2 which was called: # once (6µs+3µs) by main::_connect at line 2
use strict;
# spent 9µs making 1 call to main::BEGIN@2 # spent 3µs making 1 call to strict::import
3236µs225µs
# spent 15µs (5+10) within main::BEGIN@3 which was called: # once (5µs+10µs) by main::_connect at line 3
use warnings;
# spent 15µs making 1 call to main::BEGIN@3 # spent 10µs making 1 call to warnings::import
4package BenchmarkAnything::Storage::Frontend::Lib;
5# git description: v0.021-0-g0676cfd
6
71400nsour $AUTHORITY = 'cpan:SCHWIGON';
8# ABSTRACT: Basic functions to access a BenchmarkAnything store
91400ns$BenchmarkAnything::Storage::Frontend::Lib::VERSION = '0.022';
102135µs21.05ms
# spent 996µs (699+297) within BenchmarkAnything::Storage::Frontend::Lib::BEGIN@10 which was called: # once (699µs+297µs) by main::_connect at line 10
use Scalar::Util 'reftype';
# spent 996µs making 1 call to BenchmarkAnything::Storage::Frontend::Lib::BEGIN@10 # spent 56µs making 1 call to Exporter::import
11
12
13sub new
14
# spent 97.0ms (254µs+96.8) within BenchmarkAnything::Storage::Frontend::Lib::new which was called: # once (254µs+96.8ms) by main::_connect at line 167 of /home/ss5/perl5/perlbrew/perls/perl-5.22.0/bin/benchmarkanything-storage
{
151500ns my $class = shift;
1614µs my $self = bless { @_ }, $class;
17159µs require BenchmarkAnything::Config;
1816µs137.9ms $self->{config} = BenchmarkAnything::Config->new(cfgfile => $self->{cfgfile}) unless $self->{noconfig};
# spent 37.9ms making 1 call to BenchmarkAnything::Config::new
1913µs158.9ms $self->connect unless $self->{noconnect};
2014µs return $self;
21}
22
23sub _format_flat_inner_scalar
24{
25 my ($self, $result, $opt) = @_;
26
27241µs242µs
# spent 26µs (9+16) within BenchmarkAnything::Storage::Frontend::Lib::BEGIN@27 which was called: # once (9µs+16µs) by main::_connect at line 27
no warnings 'uninitialized';
# spent 26µs making 1 call to BenchmarkAnything::Storage::Frontend::Lib::BEGIN@27 # spent 16µs making 1 call to warnings::unimport
28
29 return "$result";
30}
31
32sub _format_flat_inner_array
33{
34 my ($self, $result, $opt) = @_;
35
36265µs218µs
# spent 12µs (6+6) within BenchmarkAnything::Storage::Frontend::Lib::BEGIN@36 which was called: # once (6µs+6µs) by main::_connect at line 36
no warnings 'uninitialized';
# spent 12µs making 1 call to BenchmarkAnything::Storage::Frontend::Lib::BEGIN@36 # spent 6µs making 1 call to warnings::unimport
37
38 return
39 join($opt->{separator},
40 map {
41 # only SCALARS allowed (where reftype returns undef)
42 die "benchmarkanything: unsupported innermost nesting (".reftype($_).") for 'flat' output.\n" if defined reftype($_);
43 "".$_
44 } @$result);
45}
46
47sub _format_flat_inner_hash
48{
49 my ($self, $result, $opt) = @_;
50
51276µs217µs
# spent 11µs (6+6) within BenchmarkAnything::Storage::Frontend::Lib::BEGIN@51 which was called: # once (6µs+6µs) by main::_connect at line 51
no warnings 'uninitialized';
# spent 11µs making 1 call to BenchmarkAnything::Storage::Frontend::Lib::BEGIN@51 # spent 6µs making 1 call to warnings::unimport
52
53 return
54 join($opt->{separator},
55 map { my $v = $result->{$_};
56 # only SCALARS allowed (where reftype returns undef)
57 die "benchmarkanything: unsupported innermost nesting (".reftype($v).") for 'flat' output.\n" if defined reftype($v);
58 "$_=".$v
59 } keys %$result);
60}
61
62sub _format_flat_outer
63{
64 my ($self, $result, $opt) = @_;
65
662443µs217µs
# spent 11µs (6+6) within BenchmarkAnything::Storage::Frontend::Lib::BEGIN@66 which was called: # once (6µs+6µs) by main::_connect at line 66
no warnings 'uninitialized';
# spent 11µs making 1 call to BenchmarkAnything::Storage::Frontend::Lib::BEGIN@66 # spent 6µs making 1 call to warnings::unimport
67
68 my $output = "";
69 die "benchmarkanything: can not flatten data structure (undef) - try other output format.\n" unless defined $result;
70
71 my $A = ""; my $B = ""; if ($opt->{fb}) { $A = "["; $B = "]" }
72 my $fi = $opt->{fi};
73
74 if (!defined reftype $result) { # SCALAR
75 $output .= $result."\n"; # stringify
76 }
77 elsif (reftype $result eq 'ARRAY') {
78 for (my $i=0; $i<@$result; $i++) {
79 my $entry = $result->[$i];
80 my $prefix = $fi ? "$i:" : "";
81 if (!defined reftype $entry) { # SCALAR
82 $output .= $prefix.$A.$self->_format_flat_inner_scalar($entry, $opt)."$B\n";
83 }
84 elsif (reftype $entry eq 'ARRAY') {
85 $output .= $prefix.$A.$self->_format_flat_inner_array($entry, $opt)."$B\n";
86 }
87 elsif (reftype $entry eq 'HASH') {
88 $output .= $prefix.$A.$self->_format_flat_inner_hash($entry, $opt)."$B\n";
89 }
90 else {
91 die "benchmarkanything: can not flatten data structure (".reftype($entry).").\n";
92 }
93 }
94 }
95 elsif (reftype $result eq 'HASH') {
96 my @keys = keys %$result;
97 foreach my $key (@keys) {
98 my $entry = $result->{$key};
99 if (!defined reftype $entry) { # SCALAR
100 $output .= "$key:".$self->_format_flat_inner_scalar($entry, $opt)."\n";
101 }
102 elsif (reftype $entry eq 'ARRAY') {
103 $output .= "$key:".$self->_format_flat_inner_array($entry, $opt)."\n";
104 }
105 elsif (reftype $entry eq 'HASH') {
106 $output .= "$key:".$self->_format_flat_inner_hash($entry, $opt)."\n";
107 }
108 else {
109 die "benchmarkanything: can not flatten data structure (".reftype($entry).").\n";
110 }
111 }
112 }
113 else {
114 die "benchmarkanything: can not flatten data structure (".reftype($result).") - try other output format.\n";
115 }
116
117 return $output;
118}
119
120sub _format_flat
121{
122 my ($self, $result, $opt) = @_;
123
124 # ensure array container
125 # for consistent output in 'getpoint' and 'search'
126 my $resultlist = reftype($result) eq 'ARRAY' ? $result : [$result];
127
128 my $output = "";
129 $opt->{separator} = ";" unless defined $opt->{separator};
130 $output .= $self->_format_flat_outer($resultlist, $opt);
131 return $output;
132}
133
134
135sub _output_format
136{
137 my ($self, $data, $opt) = @_;
138
139 my $output = "";
140 my $outtype = $opt->{outtype} || 'json';
141
142 if ($outtype eq "yaml")
143 {
144 require YAML::Any;
145 $output .= YAML::Any::Dump($data);
146 }
147 elsif ($outtype eq "json")
148 {
149 eval "use JSON -convert_blessed_universally";
150 my $json = JSON->new->allow_nonref->pretty->allow_blessed->convert_blessed;
151 $output .= $json->encode($data);
152 }
153 elsif ($outtype eq "ini") {
154 require Config::INI::Serializer;
155 my $ini = Config::INI::Serializer->new;
156 $output .= $ini->serialize($data);
157 }
158 elsif ($outtype eq "dumper")
159 {
160 require Data::Dumper;
161 $output .= Data::Dumper::Dumper($data);
162 }
163 elsif ($outtype eq "xml")
164 {
165 require XML::Simple;
166 my $xs = new XML::Simple;
167 $output .= $xs->XMLout($data, AttrIndent => 1, KeepRoot => 1);
168 }
169 elsif ($outtype eq "flat") {
170 $output .= $self->_format_flat( $data, $opt );
171 }
172 else
173 {
174 die "benchmarkanything-storage: unrecognized output format: $outtype.";
175 }
176 return $output;
177}
178
179
180sub connect
181
# spent 58.9ms (9.88+49.0) within BenchmarkAnything::Storage::Frontend::Lib::connect which was called: # once (9.88ms+49.0ms) by BenchmarkAnything::Storage::Frontend::Lib::new at line 19
{
1821500ns my ($self) = @_;
183
1841800ns my $backend = $self->{config}{benchmarkanything}{backend};
18513µs if ($backend eq 'local')
186 {
187160µs require DBI;
188190µs require BenchmarkAnything::Storage::Backend::SQL;
1892331µs224µs
# spent 16µs (7+8) within BenchmarkAnything::Storage::Frontend::Lib::BEGIN@189 which was called: # once (7µs+8µs) by main::_connect at line 189
no warnings 'once'; # avoid 'Name "DBI::errstr" used only once'
# spent 16µs making 1 call to BenchmarkAnything::Storage::Frontend::Lib::BEGIN@189 # spent 8µs making 1 call to warnings::unimport
190
191 # connect
19211µs print "Connect db...\n" if $self->{debug};
19312µs my $dsn = $self->{config}{benchmarkanything}{storage}{backend}{sql}{dsn};
19411µs my $user = $self->{config}{benchmarkanything}{storage}{backend}{sql}{user};
1951600ns my $password = $self->{config}{benchmarkanything}{storage}{backend}{sql}{password};
19613µs18.29ms my $dbh = DBI->connect($dsn, $user, $password, {'RaiseError' => 1})
# spent 8.29ms making 1 call to DBI::connect
197 or die "benchmarkanything: can not connect: ".$DBI::errstr;
198
199 # external search engine
20012µs my $searchengine = $self->{config}{benchmarkanything}{searchengine} || {};
201
202 # remember
20311µs $self->{dbh} = $dbh;
204 $self->{backend} = BenchmarkAnything::Storage::Backend::SQL->new({dbh => $dbh,
205 dbh_config => $self->{config}{benchmarkanything}{storage}{backend}{sql},
206 debug => $self->{debug},
207 force => $self->{force},
208 verbose => $self->{verbose},
209110µs139.7ms (keys %$searchengine ? (searchengine => $searchengine) : ()),
# spent 39.7ms making 1 call to BenchmarkAnything::Storage::Backend::SQL::new
210 });
211 }
212 elsif ($backend eq 'http')
213 {
214 my $ua = $self->_get_user_agent;
215 my $url = $self->_get_base_url."/api/v1/hello";
216 die "benchmarkanything: can't connect to result storage ($url)\n" if (!$ua->get($url)->res->code or $ua->get($url)->res->code != 200);
217 }
218
21913µs return $self;
220}
221
222
223sub disconnect
224
# spent 26µs (19+7) within BenchmarkAnything::Storage::Frontend::Lib::disconnect which was called: # once (19µs+7µs) by main::_disconnect at line 178 of /home/ss5/perl5/perlbrew/perls/perl-5.22.0/bin/benchmarkanything-storage
{
2251500ns my ($self) = @_;
226
22713µs my $backend = $self->{config}{benchmarkanything}{backend};
22811µs if ($backend eq 'local')
229 {
23011µs if ($self->{dbh}) {
231117µs17µs $self->{dbh}->commit unless $self->{dbh}{AutoCommit};
# spent 7µs making 1 call to DBI::common::FETCH
23211µs undef $self->{dbh}; # setting dbh to undef does better cleanup than disconnect();
233 }
234 }
23514µs return $self;
236}
237
238
239sub _are_you_sure
240{
241 my ($self) = @_;
242
243 # DSN
244 my $dsn = $self->{config}{benchmarkanything}{storage}{backend}{sql}{dsn};
245
246 # option --really
247 if ($self->{really})
248 {
249 if ($self->{really} eq $dsn)
250 {
251 return 1;
252 }
253 else
254 {
255 print STDERR "DSN does not match - asking interactive.\n";
256 }
257 }
258
259 # ask on stdin
260 print "REALLY DROP AND RE-CREATE DATABASE TABLES [$dsn] (y/N): ";
261 read STDIN, my $answer, 1;
262 return 1 if $answer && $answer =~ /^y(es)?$/i;
263
264 # default: NO
265 return 0;
266}
267
268
269sub createdb
270{
271 my ($self) = @_;
272
273 if ($self->_are_you_sure)
274 {
275230µs224µs
# spent 16µs (8+8) within BenchmarkAnything::Storage::Frontend::Lib::BEGIN@275 which was called: # once (8µs+8µs) by main::_connect at line 275
no warnings 'once'; # avoid 'Name "DBI::errstr" used only once'
# spent 16µs making 1 call to BenchmarkAnything::Storage::Frontend::Lib::BEGIN@275 # spent 8µs making 1 call to warnings::unimport
276
277 require DBI;
278 require File::Slurper;
279 require File::ShareDir;
28021.19ms1329ms
# spent 329ms (420µs+328) within BenchmarkAnything::Storage::Frontend::Lib::BEGIN@280 which was called: # once (420µs+328ms) by main::_connect at line 280
use DBIx::MultiStatementDo;
281
282 my $batch = DBIx::MultiStatementDo->new(dbh => $self->{dbh});
283
284 # get schema SQL according to driver
285 my $dsn = $self->{config}{benchmarkanything}{storage}{backend}{sql}{dsn};
286 my ($scheme, $driver, $attr_string, $attr_hash, $driver_dsn) = DBI->parse_dsn($dsn)
287 or die "benchmarkanything: can not parse DBI DSN '$dsn'";
288 my ($dbname) = $driver_dsn =~ m/database=(\w+)/g;
289 my $sql_file = File::ShareDir::dist_file('BenchmarkAnything-Storage-Backend-SQL', "create-schema.$driver");
290 my $sql = File::Slurper::read_text($sql_file);
291 $sql =~ s/^use `testrundb`;/use `$dbname`;/m if $dbname; # replace BenchmarkAnything::Storage::Backend::SQL's default
292
293 # execute schema SQL
294 my @results = $batch->do($sql);
295 if (not @results)
296 {
297 die "benchmarkanything: error while creating BenchmarkAnything DB: ".$batch->dbh->errstr;
298 }
299
300 }
301
302 return;
303}
304
305
306sub _default_additional_keys
307{
308 my ($self) = @_;
309
310 my $backend = $self->{config}{benchmarkanything}{backend};
311 if ($backend eq 'local')
312 {
313 return { $self->{backend}->default_columns };
314 }
315 else
316 {
317 # Hardcoded from BenchmarkAnything::Storage::Backend::SQL::Query::common,
318 # as it is a backend-special and internal thing anyway.
319 return {
320 'NAME' => 'b.bench',
321 'UNIT' => 'bu.bench_unit',
322 'VALUE' => 'bv.bench_value',
323 'VALUE_ID' => 'bv.bench_value_id',
324 'CREATED' => 'bv.created_at',
325 };
326 }
327}
328
- -
331sub _get_benchmark_operators
332{
333 my ($self) = @_;
334
335 my $backend = $self->{config}{benchmarkanything}{backend};
336 if ($backend eq 'local')
337 {
338 return [ $self->{backend}->benchmark_operators ];
339 }
340 else
341 {
342 # Hardcoded from BenchmarkAnything::Storage::Backend::SQL::Query::common,
343 # as it is a backend-special and internal thing anyway.
344 return [ '=', '!=', 'like', 'not like', '<', '>', '<=', '>=' ];
345 }
346}
347
- -
350sub _get_additional_key_id
351{
352 my ($self, $key_name) = @_;
353
354 my $backend = $self->{config}{benchmarkanything}{backend};
355 if ($backend eq 'local')
356 {
357 return $self->{backend}->_get_additional_key_id($key_name);
358 }
359 else
360 {
361 die "benchmarkanything: no backend '$backend' allowed here, available backends are: 'local'.\n";
362 }
363}
364
- -
367sub init_workdir
368{
369 my ($self) = @_;
370
371 require File::Basename;
372 require File::ShareDir;
373 require File::HomeDir;
374 require File::Slurper;
375
376 my $home_ba = File::HomeDir->my_home."/.benchmarkanything";
377 my $command = File::Basename::basename($0);
378
379 if (-d $home_ba)
380 {
381 print "Workdir '$home_ba' already exists - skipping.\n" if $self->{verbose};
382 }
383 else
384 {
385 require File::Path;
386 File::Path::make_path($home_ba);
387 }
388
389 foreach my $basename (qw(client.cfg server.cfg default.cfg README))
390 {
391 my $source_file = File::ShareDir::dist_file('BenchmarkAnything-Storage-Frontend-Lib', "config/$basename");
392 my $dest_file = "$home_ba/$basename";
393
394 if (! -e $dest_file)
395 {
396 my $content = File::Slurper::read_text($source_file);
397
398 # poor man's templating
399 $content =~ s{\[%\s*CLIENTCFG\s*%\]}{$home_ba/client.cfg}g;
400 $content =~ s{\[%\s*SERVERCFG\s*%\]}{$home_ba/server.cfg}g;
401 $content =~ s{\[%\s*LOCALCFG\s*%\]}{$home_ba/default.cfg}g;
402 $content =~ s{\[%\s*CFG\s*%\]}{$dest_file}g;
403 $content =~ s{\[%\s*HOME\s*%\]}{$home_ba}g;
404
405 print "Create configfile: $dest_file...\n" if $self->{verbose};
406 open my $CFGFILE, ">", $dest_file or die "Could not create $dest_file.\n";
407 print $CFGFILE $content;
408 close $CFGFILE;
409 }
410 else
411 {
412 print "Config '$dest_file' already exists - skipping.\n" if $self->{verbose};
413 }
414 }
415
416 my $dbfile = "$home_ba/benchmarkanything.sqlite";
417 my $we_created_db = 0;
418 if (! -e $dbfile)
419 {
420 print "Create storage: $dbfile...\n" if $self->{verbose};
421 __PACKAGE__->new(cfgfile => "$home_ba/default.cfg",
422 really => "dbi:SQLite:$dbfile",
423 )->createdb;
424 $we_created_db = 1;
425 }
426 else
427 {
428 print "Storage '$dbfile' already exists - skipping.\n" if $self->{verbose};
429 }
430
431 if ($self->{verbose})
432 {
433 print "\n";
434 print "By default it will use this config: $home_ba/default.cfg\n";
435 print "If you want another one, set it in your ~/.bash_profile:\n";
436 print " export BENCHMARKANYTHING_CONFIGFILE=$home_ba/client.cfg\n";
437
438 unless ($we_created_db)
439 {
440 print "\n";
441 print "Initialize a new database (it asks for confirmation) with:\n";
442 print " $command createdb\n";
443 print "\nReady.\n";
444 }
445 else
446 {
447 print "\n";
448 print "Create sample values like this:\n";
449 print qq( echo '{"BenchmarkAnythingData":[{"NAME":"benchmarkanything.hello.world", "VALUE":17.2}]}' | $command add\n);
450 print "\n";
451 print "List metric names:\n";
452 print qq( $command listnames\n);
453 print "\n";
454 print "Query sample values:\n";
455 print qq( echo '{"select":["NAME","VALUE"],"where":[["=","NAME","benchmarkanything.hello.world"]]}' | $command search\n);
456 print "\n";
457 }
458 }
459
460 return;
461}
462
463
464sub add
465{
466 my ($self, $data) = @_;
467
468 # --- validate ---
469 if (not $data)
470 {
471 die "benchmarkanything: no input data provided.\n";
472 }
473
474 if (not $self->{skipvalidation}) {
475 require BenchmarkAnything::Schema;
476 print "Verify schema...\n" if $self->{verbose};
477 if (not my $result = BenchmarkAnything::Schema::valid_json_schema($data))
478 {
479 die "benchmarkanything: add: invalid input: ".join("; ", $result->errors)."\n";
480 }
481 }
482
483 # --- add to storage ---
484
485 my $backend = $self->{config}{benchmarkanything}{backend};
486 if ($backend eq 'local')
487 {
488 my $success;
489 if ($self->{queuemode})
490 {
491 # only queue for later processing
492 print "Enqueue data [backend:local]...\n" if $self->{verbose} or $self->{debug};
493 $success = $self->{backend}->enqueue_multi_benchmark($data->{BenchmarkAnythingData});
494 }
495 else
496 {
497 print "Add data [backend:local]...\n" if $self->{verbose} or $self->{debug};
498 # preserve order, otherwise add_multi_benchmark() would reorder to optimize insert
499 foreach my $chunk (@{$data->{BenchmarkAnythingData}})
500 {
501 print "." if $self->{debug};
502 $success = $self->{backend}->add_multi_benchmark([$chunk]);
503 }
504 }
505 if (not $success)
506 {
507 die "benchmarkanything: error while adding data: ".$@;
508 }
509 print "Done.\n" if $self->{verbose} or $self->{debug};
510 }
511 elsif ($backend eq 'http')
512 {
513 require BenchmarkAnything::Reporter;
514 $self->{config} = BenchmarkAnything::Reporter->new(config => $self->{config},
515 verbose => $self->{verbose},
516 debug => $self->{debug},
517 );
518 }
519 else
520 {
521 die "benchmarkanything: no backend '$backend', available backends are: 'http', 'local'.\n";
522 }
523
524 return $self;
525}
526
527sub _get_user_agent
528{
529 require Mojo::UserAgent;
530 return Mojo::UserAgent->new;
531}
532
533sub _get_base_url
534{
535 shift->{config}{benchmarkanything}{backends}{http}{base_url};
536}
537
538
539sub search
540{
541 my ($self, $query, $value_id) = @_;
542
543 # --- validate ---
544 if (not $query and not $value_id)
545 {
546 die "benchmarkanything: no query or value_id provided.\n";
547 }
548
549 my $backend = $self->{config}{benchmarkanything}{backend};
550 if ($backend eq 'local')
551 {
552 # single values
553 return $self->{backend}->get_single_benchmark_point($value_id) if $value_id;
554 return $self->{backend}->search_array($query);
555 }
556 elsif ($backend eq 'http')
557 {
558 my $ua = $self->_get_user_agent;
559 my $url = $self->_get_base_url."/api/v1/search";
560 my $res;
561 if ($value_id) {
562 $url .= "/$value_id";
563 $res = $ua->get($url)->res;
564 } else {
565 $res = $ua->post($url => json => $query)->res;
566 }
567
568 die "benchmarkanything: ".$res->error->{message}." ($url)\n" if $res->error;
569
570 return $res->json;
571 }
572 else
573 {
574 die "benchmarkanything: no backend '$backend', available backends are: 'http', 'local'.\n";
575 }
576}
577
578
579sub listnames
580{
581 my ($self, $pattern) = @_;
582
583 my $backend = $self->{config}{benchmarkanything}{backend};
584 if ($backend eq 'local')
585 {
586 return $self->{backend}->list_benchmark_names(defined($pattern) ? ($pattern) : ());
587 }
588 elsif ($backend eq 'http')
589 {
590 my $ua = $self->_get_user_agent;
591 my $url = $self->_get_base_url."/api/v1/listnames";
592
593 my $res = $ua->get($url)->res;
594 die "benchmarkanything: ".$res->error->{message}." ($url)\n" if $res->error;
595
596 my $result = $res->json;
597
598 # output
599 return $result;
600 }
601 else
602 {
603 die "benchmarkanything: no backend '$backend', available backends are: 'http', 'local'.\n";
604 }
605}
606
607
608sub listkeys
609{
610 my ($self, $pattern) = @_;
611
612 my $backend = $self->{config}{benchmarkanything}{backend};
613 if ($backend eq 'local')
614 {
615 return $self->{backend}->list_additional_keys(defined($pattern) ? ($pattern) : ());
616 }
617 elsif ($backend eq 'http')
618 {
619 my $ua = $self->_get_user_agent;
620 my $url = $self->_get_base_url."/api/v1/listkeys";
621
622 my $res = $ua->get($url)->res;
623 die "benchmarkanything: ".$res->error->{message}." ($url)\n" if $res->error;
624
625 my $result = $res->json;
626
627 # output
628 return $result;
629 }
630 else
631 {
632 die "benchmarkanything: no backend '$backend', available backends are: 'http', 'local'.\n";
633 }
634}
635
636
637sub stats
638{
639 my ($self) = @_;
640
641 my $backend = $self->{config}{benchmarkanything}{backend};
642 if ($backend eq 'local')
643 {
644 return $self->{backend}->get_stats;
645 }
646 elsif ($backend eq 'http')
647 {
648 my $ua = $self->_get_user_agent;
649 my $url = $self->_get_base_url."/api/v1/stats";
650
651 my $res = $ua->get($url)->res;
652 die "benchmarkanything: ".$res->error->{message}." ($url)\n" if $res->error;
653
654 my $result = $res->json;
655
656 # output
657 return $result;
658 }
659 else
660 {
661 die "benchmarkanything: no backend '$backend', available backends are: 'http', 'local'.\n";
662 }
663}
664
665
666sub gc
667
# spent 34.3ms (12µs+34.3) within BenchmarkAnything::Storage::Frontend::Lib::gc which was called: # once (12µs+34.3ms) by main::_gc at line 433 of /home/ss5/perl5/perlbrew/perls/perl-5.22.0/bin/benchmarkanything-storage
{
6681400ns my ($self) = @_;
669
67013µs my $backend = $self->{config}{benchmarkanything}{backend};
67118µs134.3ms if ($backend eq 'local')
# spent 34.3ms making 1 call to BenchmarkAnything::Storage::Backend::SQL::gc
672 {
673 $self->{backend}->gc;
674 }
675}
676
677
678sub process_raw_result_queue
679
# spent 53.0s (9.64ms+53.0) within BenchmarkAnything::Storage::Frontend::Lib::process_raw_result_queue which was called: # once (9.64ms+53.0s) by main::_processqueue at line 406 of /home/ss5/perl5/perlbrew/perls/perl-5.22.0/bin/benchmarkanything-storage
{
6801400ns my ($self, $count) = @_;
681
6821300ns $count ||= 10;
683
68412µs my $backend = $self->{config}{benchmarkanything}{backend};
68511µs if ($backend eq 'local')
686 {
6871100ns my $dequeued_raw_bench_bundle_id;
68811.62ms do {
68910005.10ms100053.0s $dequeued_raw_bench_bundle_id = $self->{backend}->process_queued_multi_benchmark;
# spent 53.0s making 1000 calls to BenchmarkAnything::Storage::Backend::SQL::process_queued_multi_benchmark, avg 53.0ms/call
6901000869µs $count--;
691 } until ($count < 1 or not defined($dequeued_raw_bench_bundle_id));
692 }
693 else
694 {
695 die "benchmarkanything: only backend 'local' allowed in 'process_raw_result_queue'.\n";
696 }
69716µs return;
698}
699
700
701sub init_search_engine
702{
703 my ($self, $force) = @_;
704
705 my $backend = $self->{config}{benchmarkanything}{backend};
706 if ($backend eq 'local')
707 {
708 $self->{backend}->init_search_engine($force);
709 }
710 else
711 {
712 die "benchmarkanything: only backend 'local' allowed in 'init_search_engine'.\n";
713 }
714 return;
715}
716
717
718sub sync_search_engine
719{
720 my ($self, $force, $start, $count) = @_;
721
722 my $backend = $self->{config}{benchmarkanything}{backend};
723 if ($backend eq 'local')
724 {
725 $self->{backend}->sync_search_engine($force, $start, $count);
726 }
727 else
728 {
729 die "benchmarkanything: only backend 'local' allowed in 'sync_search_engine'.\n";
730 }
731 return;
732}
733
- -
736sub getpoint
737{
738 my ($self, $value_id) = @_;
739
740 return $self->search(undef, $value_id);
741 die "benchmarkanything: please provide a benchmark value_id'\n" unless $value_id;
742}
743
74413µs1;
745
746__END__