← Index
NYTProf Performance Profile   « block view • line view • sub view »
For /usr/local/src/github.com/foswiki/core/bin/view
  Run on Sun Dec 4 17:17:59 2011
Reported on Sun Dec 4 17:27:20 2011

Filename/usr/local/src/github.com/foswiki/core/lib/Foswiki/Query/OP_where.pm
StatementsExecuted 14 statements in 741µs
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
31161µs103µsFoswiki::Query::OP_where::::newFoswiki::Query::OP_where::new
11124µs32µsFoswiki::Query::OP_where::::BEGIN@11Foswiki::Query::OP_where::BEGIN@11
11116µs34µsFoswiki::Query::OP_where::::BEGIN@12Foswiki::Query::OP_where::BEGIN@12
1119µs9µsFoswiki::Query::OP_where::::BEGIN@14Foswiki::Query::OP_where::BEGIN@14
0000s0sFoswiki::Query::OP_where::::_evaluate_for_RHSFoswiki::Query::OP_where::_evaluate_for_RHS
0000s0sFoswiki::Query::OP_where::::evaluateFoswiki::Query::OP_where::evaluate
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# See bottom of file for license and copyright information
2
3=begin TML
4
5---+ package Foswiki::Query::OP_where
6
7=cut
8
9package Foswiki::Query::OP_where;
10
11244µs239µs
# spent 32µs (24+7) within Foswiki::Query::OP_where::BEGIN@11 which was called: # once (24µs+7µs) by Foswiki::Query::Parser::BEGIN@54 at line 11
use strict;
# spent 32µs making 1 call to Foswiki::Query::OP_where::BEGIN@11 # spent 7µs making 1 call to strict::import
12243µs251µs
# spent 34µs (16+18) within Foswiki::Query::OP_where::BEGIN@12 which was called: # once (16µs+18µs) by Foswiki::Query::Parser::BEGIN@54 at line 12
use warnings;
# spent 34µs making 1 call to Foswiki::Query::OP_where::BEGIN@12 # spent 18µs making 1 call to warnings::import
13
142575µs19µs
# spent 9µs within Foswiki::Query::OP_where::BEGIN@14 which was called: # once (9µs+0s) by Foswiki::Query::Parser::BEGIN@54 at line 14
use Foswiki::Query::OP ();
# spent 9µs making 1 call to Foswiki::Query::OP_where::BEGIN@14
1519µsour @ISA = ('Foswiki::Query::OP');
16
17
# spent 103µs (61+42) within Foswiki::Query::OP_where::new which was called 3 times, avg 34µs/call: # 3 times (61µs+42µs) by Foswiki::Query::Parser::new at line 105 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Query/Parser.pm, avg 34µs/call
sub new {
1835µs my $class = shift;
19359µs342µs return $class->SUPER::new(
# spent 42µs making 3 calls to Foswiki::Query::OP::new, avg 14µs/call
20 arity => 2,
21 name => '[',
22 close => ']',
23 prec => 900
24 );
25}
26
27sub evaluate {
28 my $this = shift;
29 my $node = shift;
30 my %domain = @_;
31
32 my $lhs_node = $node->{params}[0];
33
34 # See Foswiki/Query/Node.pm for an explanation of restricted names
35 my $lhs_values = $lhs_node->evaluate( restricted_name => 1, @_ );
36 $lhs_values = [$lhs_values] unless ( ref($lhs_values) eq 'ARRAY' );
37
38 my $rhs_node = $node->{params}[1];
39 my @res;
40 if ( ref( $rhs_node->{op} ) eq 'Foswiki::Query::OP_comma' ) {
41
42 # We have an array on the RHS. We apply the op to each item
43 # on the RHS, passing in the complete LHS. This way, the operation
44 # [a,b,c] WHERE [1,3] -> [a,c]
45 # This process permits duplication of entries in the result.
46 foreach my $rhs_item ( @{ $rhs_node->{params} } ) {
47 $this->_evaluate_for_RHS( $lhs_values, $rhs_item, \%domain, \@res );
48 }
49 }
50 else {
51 $this->_evaluate_for_RHS( $lhs_values, $rhs_node, \%domain, \@res );
52 }
53 return unless scalar(@res);
54 return \@res;
55}
56
57# Give a set of values on the LHS of a where, and a single constraint
58# on the RHS, create a set of results. The results are selected from the
59# LHS, by index. For example, given [a,b,c] WHERE d then if d evaluates
60# to a constant integer, then it is taken as an index into [a,b,c]. Otherwise
61# it is evaluated and if it returns true, then the LHS entry at the
62# corresponding position is returned. So:
63# [a,b,c] WHERE 1 -> [b]
64# [a,b,c] WHERE name!='b' -> [a,c]
65sub _evaluate_for_RHS {
66 my ( $this, $lhs_values, $rhs_node, $domain, $res ) = @_;
67
68 # See if we have an index on the RHS
69 my $rhs_constant = -1;
70 if ( $rhs_node->evaluatesToConstant(%$domain) ) {
71 $rhs_constant = $rhs_node->evaluate(%$domain);
72 if ( Foswiki::Query::OP::isNumber($rhs_constant) ) {
73
74 # Handle negative indices
75 $rhs_constant += scalar(@$lhs_values) if ( $rhs_constant < 0 );
76
77 # Trunc to integer
78 $rhs_constant = int($rhs_constant);
79
80 # Don't bother if integer index is out of range
81 return
82 unless $rhs_constant >= 0
83 && $rhs_constant < scalar(@$lhs_values);
84 }
85 else {
86 $rhs_constant = -1; # unmatchable
87 }
88 }
89
90 # For each item on the LHS
91 my $i = 0; # LHS index
92 foreach my $lhs_value (@$lhs_values) {
93 if ( $rhs_constant < 0
94 && $rhs_node->evaluate( data => $lhs_value, tom => $domain->{tom} )
95 )
96 {
97 push( @$res, $lhs_value );
98 }
99 elsif ( $i == $rhs_constant ) {
100
101 # Special case; integer index responds with array el at that index
102 push( @$res, $lhs_value );
103 }
104 $i++;
105 }
106}
107
10816µs1;
109__END__