← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 18:42:36 2015
Reported on Fri Jul 31 18:48:16 2015

Filename/var/www/foswikidev/core/lib/Foswiki/Store/Interfaces/QueryAlgorithm.pm
StatementsExecuted 258766 statements in 847ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1752011806ms53.9sFoswiki::Store::Interfaces::QueryAlgorithm::::__ANON__[:194]Foswiki::Store::Interfaces::QueryAlgorithm::__ANON__[:194]
876011109ms162msFoswiki::Store::Interfaces::QueryAlgorithm::::getFieldFoswiki::Store::Interfaces::QueryAlgorithm::getField
80118.89ms108sFoswiki::Store::Interfaces::QueryAlgorithm::::queryFoswiki::Store::Interfaces::QueryAlgorithm::query (recurses: max depth 1, inclusive time 49.2s)
80112.40ms8.41msFoswiki::Store::Interfaces::QueryAlgorithm::::getWebIteratorFoswiki::Store::Interfaces::QueryAlgorithm::getWebIterator
80112.19ms4.55msFoswiki::Store::Interfaces::QueryAlgorithm::::getListOfWebsFoswiki::Store::Interfaces::QueryAlgorithm::getListOfWebs
80112.06ms3.12msFoswiki::Store::Interfaces::QueryAlgorithm::::addACLFilterFoswiki::Store::Interfaces::QueryAlgorithm::addACLFilter
1111.79ms1.90msFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@17Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@17
80111.57ms15.0msFoswiki::Store::Interfaces::QueryAlgorithm::::__ANON__[:235]Foswiki::Store::Interfaces::QueryAlgorithm::__ANON__[:235]
8011925µs157sFoswiki::Store::Interfaces::QueryAlgorithm::::__ANON__[:119]Foswiki::Store::Interfaces::QueryAlgorithm::__ANON__[:119]
8011503µs503µsFoswiki::Store::Interfaces::QueryAlgorithm::::addPagerFoswiki::Store::Interfaces::QueryAlgorithm::addPager
111437µs522µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@20Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@20
111402µs606µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@9Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@9
111302µs400µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@8Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@8
22217µs17µsFoswiki::Store::Interfaces::QueryAlgorithm::::newFoswiki::Store::Interfaces::QueryAlgorithm::new
11115µs27µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@4Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@4
11114µs41µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@344Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@344
11111µs41µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@6Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@6
1119µs13µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@5Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@5
1119µs42µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@30Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@30
1116µs6µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@18Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@18
1115µs5µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@10Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@10
1115µs5µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@21Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@21
1115µs5µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@19Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@19
1115µs5µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@23Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@23
1114µs4µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@11Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@11
1114µs4µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@16Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@16
1114µs4µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@14Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@14
1113µs3µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@12Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@12
1113µs3µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@15Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@15
1113µs3µsFoswiki::Store::Interfaces::QueryAlgorithm::::BEGIN@13Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@13
0000s0sFoswiki::Store::Interfaces::QueryAlgorithm::::getFormFoswiki::Store::Interfaces::QueryAlgorithm::getForm
0000s0sFoswiki::Store::Interfaces::QueryAlgorithm::::getRefTopicFoswiki::Store::Interfaces::QueryAlgorithm::getRefTopic
0000s0sFoswiki::Store::Interfaces::QueryAlgorithm::::getRev1InfoFoswiki::Store::Interfaces::QueryAlgorithm::getRev1Info
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
2package Foswiki::Store::Interfaces::QueryAlgorithm;
3
4228µs238µs
# spent 27µs (15+11) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@4 which was called: # once (15µs+11µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 4
use strict;
# spent 27µs making 1 call to Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@4 # spent 11µs making 1 call to strict::import
5224µs217µs
# spent 13µs (9+4) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@5 which was called: # once (9µs+4µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 5
use warnings;
# spent 13µs making 1 call to Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@5 # spent 4µs making 1 call to warnings::import
6227µs272µs
# spent 41µs (11+31) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@6 which was called: # once (11µs+31µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 6
use Assert;
# spent 41µs making 1 call to Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@6 # spent 31µs making 1 call to Exporter::import
7
8290µs1400µs
# spent 400µs (302+98) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@8 which was called: # once (302µs+98µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 8
use Foswiki::Store::Interfaces::SearchAlgorithm ();
# spent 400µs making 1 call to Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@8
92101µs1606µs
# spent 606µs (402+204) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@9 which was called: # once (402µs+204µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 9
use Foswiki::Search::Node ();
# spent 606µs making 1 call to Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@9
10222µs15µs
# spent 5µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@10 which was called: # once (5µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 10
use Foswiki::Search::InfoCache ();
11220µs14µs
# spent 4µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@11 which was called: # once (4µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 11
use Foswiki::Search::ResultSet ();
12219µs13µs
# spent 3µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@12 which was called: # once (3µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 12
use Foswiki();
13220µs13µs
# spent 3µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@13 which was called: # once (3µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 13
use Foswiki::Func();
14220µs14µs
# spent 4µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@14 which was called: # once (4µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 14
use Foswiki::Meta ();
15219µs13µs
# spent 3µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@15 which was called: # once (3µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 15
use Foswiki::MetaCache ();
16220µs14µs
# spent 4µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@16 which was called: # once (4µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 16
use Foswiki::Query::Node ();
172117µs11.90ms
# spent 1.90ms (1.79+101µs) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@17 which was called: # once (1.79ms+101µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 17
use Foswiki::Query::HoistREs ();
18224µs16µs
# spent 6µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@18 which was called: # once (6µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 18
use Foswiki::ListIterator();
19221µs15µs
# spent 5µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@19 which was called: # once (5µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 19
use Foswiki::Iterator::FilterIterator();
20296µs1522µs
# spent 522µs (437+85) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@20 which was called: # once (437µs+85µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 20
use Foswiki::Iterator::ProcessIterator();
21244µs15µs
# spent 5µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@21 which was called: # once (5µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 21
use Foswiki::Iterator::PagerIterator();
22
23
# spent 5µs within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@23 which was called: # once (5µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 28
BEGIN {
2415µs if ( $Foswiki::cfg{UseLocale} ) {
25 require locale;
26 import locale();
27 }
28123µs15µs}
29
3021.06ms275µs
# spent 42µs (9+33) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@30 which was called: # once (9µs+33µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 30
use constant MONITOR => 0;
# spent 42µs making 1 call to Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@30 # spent 33µs making 1 call to constant::import
31
32=begin TML
33
34---+ package Foswiki::Store::Interfaces::QueryAlgorithm
35
36Interface to query algorithms.
37Implementations of this interface are found in Foswiki/Store/*Algorithms.
38
39The contract with query algorithms is specified by this interface description,
40plus the 'query' unit tests in Fn_SEARCH.
41The interface provides a default implementation of the 'getField' method,
42but all other methods are pure virtual and must be provided by subclasses.
43Note that if a subclass re-implements getField, then there is no direct
44need to inherit from this class (as long as all the methods are implemented).
45
46=cut
47
48=begin TML
49
50---++ ClassMethod new( $class, ) -> $cereal
51
52=cut
53
54
# spent 17µs within Foswiki::Store::Interfaces::QueryAlgorithm::new which was called 2 times, avg 8µs/call: # once (9µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::new at line 62 of /var/www/foswikidev/core/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm # once (8µs+0s) by Foswiki::Store::SearchAlgorithms::Forking::new at line 50 of /var/www/foswikidev/core/lib/Foswiki/Store/SearchAlgorithms/Forking.pm
sub new {
5521µs my $class = shift;
56213µs my $this = bless( {}, $class );
57212µs return $this;
58}
59
60=begin TML
61
62---++ ObjectMethod query( $query, $webs, $inputTopicSet, $session, $options ) -> $infoCache
63 * =$query= - A Foswiki::Query::Node object
64 * =$web= - name of the web being searched, or may be an array reference
65 to a set of webs to search
66 * =$inputTopicSet= - iterator over names of topics in that web to search
67 * =$session= - reference to the store object
68 * =$options= - hash of requested options
69This is the top-level interface to a query algorithm. A store module can call
70this method to start the 'hard work' query process. That process will call
71back to the =getField= method in this module to evaluate leaf data in the
72store.
73
74To monitor the hoisting and evaluation processes, use the MONITOR_EVAL
75setting in Foswiki::Query::Node
76
77this is a default implementation of the query() sub that uses the specific algorithms' _webQuery member function.
78
79=cut
80
81
# spent 108s (8.89ms+108) within Foswiki::Store::Interfaces::QueryAlgorithm::query which was called 80 times, avg 1.35s/call: # 80 times (8.89ms+108s) by Foswiki::Store::Rcs::Store::query at line 666 of /var/www/foswikidev/core/lib/Foswiki/Store/Rcs/Store.pm, avg 1.35s/call
sub query {
828073µs my ( $this, $query, $inputTopicSet, $session, $options ) = @_;
83
8480265µs80289µs if ( $query->isEmpty() )
# spent 150µs making 40 calls to Foswiki::Search::Node::isEmpty, avg 4µs/call # spent 139µs making 40 calls to Foswiki::Query::Node::isEmpty, avg 3µs/call
85 { #TODO: does this do anything in a type=query context?
86 #Note: Must return an empty results set, including pager, to avoid crash. Item13383
87 my $resultset =
88 new Foswiki::Search::ResultSet( [], $options->{groupby},
89 $options->{order}, Foswiki::isTrue( $options->{reverse} ) );
90 return $this->addPager( $resultset, $options );
91 }
92
9380107µs my $date = $options->{'date'} || '';
94
95 # Fold constants
9680218µs80786µs my $context = Foswiki::Meta->new( $session, $session->{webName} );
# spent 786µs making 80 calls to Foswiki::Meta::new, avg 10µs/call
97 print STDERR "--- before: " . $query->stringify() . "\n" if MONITOR;
9880294µs803.80ms $query->simplify( tom => $context, data => $context );
# spent 3.69ms making 40 calls to Foswiki::Query::Node::simplify, avg 92µs/call # spent 108µs making 40 calls to Foswiki::Search::Node::simplify, avg 3µs/call
99 print STDERR "--- simplified: " . $query->stringify() . "\n" if MONITOR;
100
10180212µs808.41ms my $webItr = $this->getWebIterator( $session, $options );
# spent 8.41ms making 80 calls to Foswiki::Store::Interfaces::QueryAlgorithm::getWebIterator, avg 105µs/call
102
103 #do the search
104 my $queryItr = Foswiki::Iterator::ProcessIterator->new(
105 $webItr,
106
# spent 157s (925µs+157) within Foswiki::Store::Interfaces::QueryAlgorithm::__ANON__[/var/www/foswikidev/core/lib/Foswiki/Store/Interfaces/QueryAlgorithm.pm:119] which was called 80 times, avg 1.97s/call: # 80 times (925µs+157s) by Foswiki::Iterator::ProcessIterator::next at line 58 of /var/www/foswikidev/core/lib/Foswiki/Iterator/ProcessIterator.pm, avg 1.97s/call
sub {
1078031µs my $web = shift;
1088019µs my $params = shift;
109
11080293µs80157s my $infoCache =
# spent 108s making 40 calls to Foswiki::Store::QueryAlgorithms::BruteForce::_webQuery, avg 2.70s/call # spent 49.1s making 40 calls to Foswiki::Store::SearchAlgorithms::Forking::_webQuery, avg 1.23s/call
111 $this->_webQuery( $params->{query}, $web, $params->{inputset},
112 $params->{session}, $params->{options} );
113
1148042µs if ($date) {
115 $infoCache->filterByDate($date);
116 }
117
11880506µs return $infoCache;
119 },
120 {
12180739µs80465µs query => $query,
# spent 465µs making 80 calls to Foswiki::Iterator::ProcessIterator::new, avg 6µs/call
122 inputset => $inputTopicSet,
123 session => $session,
124 options => $options
125 }
126 );
127
128#sadly, the resultSet currently wants a real array, rather than an unevaluated web iterator
12980293µs80108s my @resultCacheList = $queryItr->all();
# spent 157s making 80 calls to Foswiki::Iterator::ProcessIterator::all, avg 1.97s/call, recursion: max depth 1, sum of overlapping time 49.1s
130
131#and thus if the ResultSet could be created using an unevaluated process itr, which would somehow rely on........ eeeeek
132801.69ms1602.21ms my $resultset =
# spent 1.53ms making 80 calls to Foswiki::Search::ResultSet::new, avg 19µs/call # spent 681µs making 80 calls to Foswiki::isTrue, avg 9µs/call
133 new Foswiki::Search::ResultSet( \@resultCacheList, $options->{groupby},
134 $options->{order}, Foswiki::isTrue( $options->{reverse} ) );
135
136 #add permissions check
13780484µs803.12ms $resultset = $this->addACLFilter( $resultset, $options );
# spent 3.12ms making 80 calls to Foswiki::Store::Interfaces::QueryAlgorithm::addACLFilter, avg 39µs/call
138
139 #sort as late as possible
14080311µs80182ms $resultset->sortResults($options);
# spent 182ms making 80 calls to Foswiki::Iterator::FilterIterator::sortResults, avg 2.28ms/call
141
142 #add paging if applicable.
143803.75ms80503µs $this->addPager( $resultset, $options );
# spent 503µs making 80 calls to Foswiki::Store::Interfaces::QueryAlgorithm::addPager, avg 6µs/call
144}
145
146
# spent 503µs within Foswiki::Store::Interfaces::QueryAlgorithm::addPager which was called 80 times, avg 6µs/call: # 80 times (503µs+0s) by Foswiki::Store::Interfaces::QueryAlgorithm::query at line 143, avg 6µs/call
sub addPager {
1478070µs my $this = shift;
1488029µs my $resultset = shift;
1498029µs my $options = shift;
150
15180100µs if ( $options->{paging_on} ) {
152 $resultset =
153 new Foswiki::Iterator::PagerIterator( $resultset,
154 $options->{pagesize}, $options->{showpage} );
155 }
156
15780321µs return $resultset;
158}
159
160
# spent 3.12ms (2.06+1.05) within Foswiki::Store::Interfaces::QueryAlgorithm::addACLFilter which was called 80 times, avg 39µs/call: # 80 times (2.06ms+1.05ms) by Foswiki::Store::Interfaces::QueryAlgorithm::query at line 137, avg 39µs/call
sub addACLFilter {
1618047µs my $this = shift;
1628018µs my $resultset = shift;
1638026µs my $options = shift;
164
165 #add filtering for ACL test - probably should make it a seperate filter
166 $resultset = new Foswiki::Iterator::FilterIterator(
167 $resultset,
168
# spent 53.9s (806ms+53.1) within Foswiki::Store::Interfaces::QueryAlgorithm::__ANON__[/var/www/foswikidev/core/lib/Foswiki/Store/Interfaces/QueryAlgorithm.pm:194] which was called 17520 times, avg 3.08ms/call: # 17520 times (806ms+53.1s) by Foswiki::Iterator::FilterIterator::hasNext at line 73 of /var/www/foswikidev/core/lib/Foswiki/Iterator/FilterIterator.pm, avg 3.08ms/call
sub {
169175203.90ms my $listItem = shift;
170175202.59ms my $params = shift;
171
172 #ACL test
1731752026.6ms17520251ms my ( $web, $topic ) =
# spent 251ms making 17520 calls to Foswiki::Func::normalizeWebTopicName, avg 14µs/call
174 Foswiki::Func::normalizeWebTopicName( '', $listItem );
175
1761752060.7ms5256052.1s my $topicMeta =
# spent 52.1s making 17520 calls to Foswiki::MetaCache::addMeta, avg 2.97ms/call # spent 29.7ms making 17520 calls to Foswiki::search, avg 2µs/call # spent 25.5ms making 17520 calls to Foswiki::Search::metacache, avg 1µs/call
177 $Foswiki::Plugins::SESSION->search->metacache->addMeta( $web,
178 $topic );
179175202.08ms if ( not defined($topicMeta) ) {
180
181#TODO: OMG! Search.pm relies on Meta::load (in the metacache) returning a meta object even when the topic does not exist.
182#lets change that
183 $topicMeta =
184 new Foswiki::Meta( $Foswiki::Plugins::SESSION, $web, $topic );
185 }
1861752059.7ms52560734ms my $info =
# spent 680ms making 17520 calls to Foswiki::MetaCache::get, avg 39µs/call # spent 29.4ms making 17520 calls to Foswiki::search, avg 2µs/call # spent 24.1ms making 17520 calls to Foswiki::Search::metacache, avg 1µs/call
187 $Foswiki::Plugins::SESSION->search->metacache->get( $web, $topic,
188 $topicMeta );
189 ##ASSERT( defined( $info->{tom} ) ) if DEBUG;
190
191# Check security (don't show topics the current user does not have permission to view)
192175207.46ms return 0 unless ( $info->{allowView} );
19317520550ms return 1;
194 },
195801.92ms801.05ms $options
# spent 1.05ms making 80 calls to Foswiki::Iterator::FilterIterator::new, avg 13µs/call
196 );
197}
198
199
# spent 8.41ms (2.40+6.01) within Foswiki::Store::Interfaces::QueryAlgorithm::getWebIterator which was called 80 times, avg 105µs/call: # 80 times (2.40ms+6.01ms) by Foswiki::Store::Interfaces::QueryAlgorithm::query at line 101, avg 105µs/call
sub getWebIterator {
2008028µs my $this = shift;
2018026µs my $session = shift;
2028017µs my $options = shift;
203
2048060µs my $webNames = $options->{web} || '';
2058064µs my $recurse = $options->{'recurse'} || '';
20680336µs80432µs my $isAdmin = $session->{users}->isAdmin( $session->{user} );
# spent 432µs making 80 calls to Foswiki::Users::isAdmin, avg 5µs/call
207
208 #get a complete list of webs to search
20980224µs my $searchAllFlag = ( $webNames =~ m/(^|[\,\s])(all|on)([\,\s]|$)/i );
21080305µs804.55ms my @webs =
# spent 4.55ms making 80 calls to Foswiki::Store::Interfaces::QueryAlgorithm::getListOfWebs, avg 57µs/call
211 Foswiki::Store::Interfaces::QueryAlgorithm::getListOfWebs( $webNames,
212 $recurse, $searchAllFlag );
21380358µs80548µs my $rawWebIter = new Foswiki::ListIterator( \@webs );
# spent 548µs making 80 calls to Foswiki::ListIterator::new, avg 7µs/call
214 my $webItr = new Foswiki::Iterator::FilterIterator(
215 $rawWebIter,
216
# spent 15.0ms (1.57+13.4) within Foswiki::Store::Interfaces::QueryAlgorithm::__ANON__[/var/www/foswikidev/core/lib/Foswiki/Store/Interfaces/QueryAlgorithm.pm:235] which was called 80 times, avg 187µs/call: # 80 times (1.57ms+13.4ms) by Foswiki::Iterator::FilterIterator::hasNext at line 73 of /var/www/foswikidev/core/lib/Foswiki/Iterator/FilterIterator.pm, avg 187µs/call
sub {
2178025µs my $web = shift;
2188017µs my $params = shift;
219
220 # can't process what ain't thar
22180280µs805.88ms return 0 unless $session->webExists($web);
# spent 5.88ms making 80 calls to Foswiki::webExists, avg 74µs/call
222
22380245µs80863µs my $webObject = Foswiki::Meta->new( $session, $web );
# spent 863µs making 80 calls to Foswiki::Meta::new, avg 11µs/call
22480310µs1606.64ms my $thisWebNoSearchAll =
# spent 5.92ms making 80 calls to Foswiki::Meta::getPreference, avg 74µs/call # spent 721µs making 80 calls to Foswiki::isTrue, avg 9µs/call
225 Foswiki::isTrue( $webObject->getPreference('NOSEARCHALL') );
226
227 # make sure we can report this web on an 'all' search
228 # DON'T filter out unless it's part of an 'all' search.
2298020µs return 0
230 if ( $searchAllFlag
231 && !$isAdmin
232 && ( $thisWebNoSearchAll || $web =~ m/^[\.\_]/ )
233 && $web ne $session->{webName} );
23480394µs return 1;
235 },
236 {}
23780873µs80477µs );
# spent 477µs making 80 calls to Foswiki::Iterator::FilterIterator::new, avg 6µs/call
238}
239
240=begin TML
241
242---++ StaticMethod getField($class, $node, $data, $field ) -> $result
243 * =$class= is this package
244 * =$node= is the query node
245 * =$data= is the indexed object
246 * =$field= is the scalar being used to index the object
247=getField= is used by the query evaluation code in Foswiki::Query::Node to get
248information about a leaf node, or 'field'. A field can be a name, or a literal,
249and the information it refers to can be a scalar, a reference to a hash, or
250a reference to an array. The exact interpretation of fields is
251context-dependant, according to reasonably complex rules best documented by
252the Fn_SEARCH unit test and System.QuerySearch.
253
254The function must map the query schema to whatever the underlying
255store uses to store a topic. See System.QuerySearch for more information
256on the query schema.
257
258=cut
259
260# Implements Foswiki::Store::Interfaces::QueryAlgorithm
261
# spent 162ms (109+52.5) within Foswiki::Store::Interfaces::QueryAlgorithm::getField which was called 8760 times, avg 18µs/call: # 8760 times (109ms+52.5ms) by Foswiki::Query::Node::_getField at line 242 of /var/www/foswikidev/core/lib/Foswiki/Query/Node.pm, avg 18µs/call
sub getField {
262
263 # The getField function allows for Store specific optimisations
264 # such as direct database lookups. The default implementation
265 # works with the Foswiki::Meta object.
26687605.53ms my ( $this, $node, $data, $field ) = @_;
267
26887601.11ms my $result;
269 ASSERT( UNIVERSAL::isa( $data, 'Foswiki::Meta' ) ) if DEBUG;
270
2718760661µs print STDERR "\n----- getField($field)\n" if MONITOR;
272
27387602.85ms if ( $field eq 'META:VERSIONS' ) {
274
275 # Disallow reloading versions for an object loaded here
276 # SMELL: violates Foswiki::Meta encapsulation
277 return [] if $data->{_loadedByQueryAlgorithm};
278
279 # Oooh, this is inefficient.
280 my $it = $data->getRevisionHistory();
281 my @revs;
282 while ( $it->hasNext() ) {
283 my $n = $it->next();
284 my $t =
285 $this->getRefTopic( $data, $data->web(), $data->topic(), $n );
286 $t->{_loadedByQueryAlgorithm} = 1;
287 push( @revs, $t );
288 }
289 return \@revs;
290 }
291
29287606.74ms if ( $field =~ s/^META:// ) {
293 if ( $field eq 'TOPICINFO' ) {
294
295 # Ensure the revision info is populated from the store
296 $data->getRevisionInfo();
297 }
298
299 if ( $Foswiki::Query::Node::isArrayType{$field} ) {
300
301 # Array type, have to use find
302 my @e = $data->find($field);
303 return \@e;
304 }
305 return $data->get($field);
306 }
307
30887601.12ms if ( $field eq 'name' ) {
309
310 # Special accessor to compensate for lack of a topic
311 # name anywhere in the saved fields of meta
312 return $data->topic();
313 }
314
31587601.02ms if ( $field eq 'text' ) {
316
317 # Special accessor to compensate for lack of the topic text
318 # name anywhere in the saved fields of meta
319 return $data->text();
320 }
321
32287601.02ms if ( $field eq 'web' ) {
323
324 # Special accessor to compensate for lack of a web
325 # name anywhere in the saved fields of meta
326 return $data->web();
327 }
328
32987601.00ms if ( $field eq ':topic_meta:' ) {
330
331 #TODO: Sven expects this to be replaced with a fast call to
332 # versions[0] - atm, thats needlessly slow
333 # return the meta obj itself
334 # actually should do this the way the versions feature is
335 # supposed to return a particular one..
336 # SMELL: CDot can't work out what this is for....
337 return $data;
338 }
339
340876010.5ms876018.2ms return undef unless $data->topic();
# spent 18.2ms making 8760 calls to Foswiki::Meta::topic, avg 2µs/call
341
342 if (MONITOR) {
343 print STDERR "----- getField(FIELD value $field)\n";
3442768µs268µs
# spent 41µs (14+27) within Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@344 which was called: # once (14µs+27µs) by Foswiki::Store::QueryAlgorithms::BruteForce::BEGIN@29 at line 344
use Data::Dumper;
# spent 41µs making 1 call to Foswiki::Store::Interfaces::QueryAlgorithm::BEGIN@344 # spent 27µs making 1 call to Exporter::import
345 print STDERR Dumper($data) . "\n";
346 }
347
348 # SHORTCUT; not a predefined name; assume it's a field
349 # 'name' instead.
350876012.0ms876034.3ms $result = $data->get( 'FIELD', $field );
# spent 34.3ms making 8760 calls to Foswiki::Meta::get, avg 4µs/call
35187606.01ms $result = $result->{value} if $result;
352876064.6ms return $result;
353}
354
355=begin TML
356
357---++ StaticMethod getForm($class, $node, $data, $field ) -> $result
358 * =$class= is this package
359 * =$node= is the query node
360 * =$data= is the indexed object (must be Foswiki::Meta)
361 * =$formname= is the required form name
362
363=cut
364
365sub getForm {
366 my ( $this, $node, $data, $formname ) = @_;
367 return undef unless $data->topic();
368
369 my $form = $data->get('FORM');
370 return undef unless $form && $formname eq $form->{name};
371 print STDERR "----- getForm($formname)\n" if MONITOR;
372
373 # TODO: This is where multiple form support needs to reside.
374 # Return the array of FIELD for further indexing.
375 my @e = $data->find('FIELD');
376 return \@e;
377}
378
379=begin TML
380
381---++ StaticMethod getRefTopic($class, $relativeTo, $web, $topic, $rev) -> $topic
382 * =$class= is this package
383 * =$relativeTo= is a pointer into the data structure of this module where
384 the ref is relative to; for example, in the expression
385 "other/'Web.Topic'" then =$relativeTo= is =other=.
386 * =$web= the web; =Web= in the above example
387 * =$topic= the topic; =Topic= in the above example
388 * =$rev= optional revision to load
389This method supports the =Foswiki::Query::OP_ref= and =Foswiki::Query::OP_at=
390operators by abstracting the loading of a topic referred to in a string.
391
392=cut
393
394# Default implements gets a new Foswiki::Meta
395sub getRefTopic {
396
397 # Get a referenced topic
398 my ( $this, $relativeTo, $w, $t, $rev ) = @_;
399 my $meta = Foswiki::Meta->load( $relativeTo->session, $w, $t, $rev );
400 print STDERR "----- getRefTopic($w, $t) -> "
401 . ( $meta->getLoadedRev() ) . "\n"
402 if MONITOR;
403 return $meta;
404}
405
406=begin TML
407
408---++ StaticMethod getRev1Info($meta) -> %info
409
410Return revision info for the first revision in %info with at least:
411 * ={date}= in epochSec
412 * ={author}= canonical user ID
413 * ={version}= the revision number
414
415=cut
416
417# Default implements gets a new Foswiki::Meta
418sub getRev1Info {
419 my $this = shift;
420 my $meta = shift;
421
422 my $wikiname = $meta->getRev1Info('createwikiname');
423 return $meta->{_getRev1Info}->{rev1info};
424}
425
426=begin TML
427
428---+ getListOfWebs($webnames, $recurse, $serachAllFlag) -> @webs
429
430Convert a comma separated list of webs into the list we'll process
431TODO: this is part of the Store now, and so should not need to reference
432Meta - it rather uses the store.
433
434=cut
435
436
# spent 4.55ms (2.19+2.36) within Foswiki::Store::Interfaces::QueryAlgorithm::getListOfWebs which was called 80 times, avg 57µs/call: # 80 times (2.19ms+2.36ms) by Foswiki::Store::Interfaces::QueryAlgorithm::getWebIterator at line 210, avg 57µs/call
sub getListOfWebs {
43780109µs my ( $webName, $recurse, $searchAllFlag ) = @_;
4388031µs my $session = $Foswiki::Plugins::SESSION;
439
4408011µs my %excludeWeb;
4418018µs my @tmpWebs;
442
443 #$web = Foswiki::Sandbox::untaint( $web,\&Foswiki::Sandbox::validateWebName );
444
4458052µs if ($webName) {
44640109µs foreach my $web ( split( /[\,\s]+/, $webName ) ) {
4474065µs $web =~ s#\.#/#g;
448
449 # the web processing loop filters for valid web names,
450 # so don't do it here.
4514072µs if ( $web =~ s/^-// ) {
452 $excludeWeb{$web} = 1;
453 }
454 else {
45540164µs40350µs if ( $web =~ m/^(all|on)$/i
# spent 350µs making 40 calls to Foswiki::isTrue, avg 9µs/call
456 || $Foswiki::cfg{EnableHierarchicalWebs}
457 && Foswiki::isTrue($recurse) )
458 {
459 my $webObject;
460 my $prefix = "$web/";
461 if ( $web =~ m/^(all|on)$/i ) {
462 $webObject = Foswiki::Meta->new($session);
463 $prefix = '';
464 }
465 else {
466 $web = Foswiki::Sandbox::untaint( $web,
467 \&Foswiki::Sandbox::validateWebName );
468 ASSERT($web) if DEBUG;
469 push( @tmpWebs, $web );
470 $webObject = Foswiki::Meta->new( $session, $web );
471 }
472 my $it = $webObject->eachWeb(1);
473 while ( $it->hasNext() ) {
474 my $w = $prefix . $it->next();
475 next
476 unless Foswiki::WebFilter->user_allowed()
477 ->ok( $session, $w );
478 $w = Foswiki::Sandbox::untaint( $w,
479 \&Foswiki::Sandbox::validateWebName );
480 ASSERT($web) if DEBUG;
481 push( @tmpWebs, $w );
482 }
483 }
484 else {
48540104µs40605µs $web = Foswiki::Sandbox::untaint( $web,
# spent 605µs making 40 calls to Foswiki::Sandbox::untaint, avg 15µs/call
486 \&Foswiki::Sandbox::validateWebName );
4874030µs push( @tmpWebs, $web );
488 }
489 }
490 }
491
492 }
493 else {
494
495 # default to current web
49640226µs401.12ms my $web =
# spent 1.12ms making 40 calls to Foswiki::Sandbox::untaint, avg 28µs/call
497 Foswiki::Sandbox::untaint( $session->{webName},
498 \&Foswiki::Sandbox::validateWebName );
4994038µs push( @tmpWebs, $web );
5004061µs40283µs if ( Foswiki::isTrue($recurse) ) {
# spent 283µs making 40 calls to Foswiki::isTrue, avg 7µs/call
501 require Foswiki::Meta;
502 my $webObject = Foswiki::Meta->new( $session, $session->{webName} );
503 my $it =
504 $webObject->eachWeb( $Foswiki::cfg{EnableHierarchicalWebs} );
505 while ( $it->hasNext() ) {
506 my $w = $session->{webName} . '/' . $it->next();
507 next
508 unless Foswiki::WebFilter->user_allowed()->ok( $session, $w );
509 $w = Foswiki::Sandbox::untaint( $w,
510 \&Foswiki::Sandbox::validateWebName );
511 push( @tmpWebs, $w );
512 }
513 }
514 }
515
5168024µs my @webs;
5178099µs foreach my $web (@tmpWebs) {
5188014µs next unless defined $web;
51980108µs push( @webs, $web ) unless $excludeWeb{$web};
52080130µs $excludeWeb{$web} = 1; # eliminate duplicates
521 }
522
523 # Default to alphanumeric sort order
52480484µs return sort @webs;
525}
526
52712µs1;
528__END__