← 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:26:50 2011

Filename/usr/local/src/github.com/foswiki/core/lib/Foswiki/Search/InfoCache.pm
StatementsExecuted 7254 statements in 74.0ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
34251145.5ms63.8msFoswiki::Search::InfoCache::::__ANON__[:424]Foswiki::Search::InfoCache::__ANON__[:424]
34494111.1ms11.1msFoswiki::Search::InfoCache::::CORE:matchFoswiki::Search::InfoCache::CORE:match (opcode)
3427317.33ms7.33msFoswiki::Search::InfoCache::::CORE:regcompFoswiki::Search::InfoCache::CORE:regcomp (opcode)
1111.18ms1.34msFoswiki::Search::InfoCache::::BEGIN@26Foswiki::Search::InfoCache::BEGIN@26
2211873µs2.20msFoswiki::Search::InfoCache::::addTopicsFoswiki::Search::InfoCache::addTopics
111374µs548µsFoswiki::Search::InfoCache::::sortTopicsFoswiki::Search::InfoCache::sortTopics
222183µs753µsFoswiki::Search::InfoCache::::sortResultsFoswiki::Search::InfoCache::sortResults
11169µs209µsFoswiki::Search::InfoCache::::getOptionFilterFoswiki::Search::InfoCache::getOptionFilter
11167µs170msFoswiki::Search::InfoCache::::getTopicListIteratorFoswiki::Search::InfoCache::getTopicListIterator
11167µs99µsFoswiki::Search::InfoCache::::newFoswiki::Search::InfoCache::new
11165µs115µsFoswiki::Search::InfoCache::::convertTopicPatternToRegexFoswiki::Search::InfoCache::convertTopicPatternToRegex
11161µs61µsFoswiki::Search::InfoCache::::CORE:sortFoswiki::Search::InfoCache::CORE:sort (opcode)
11129µs36µsFoswiki::Search::InfoCache::::BEGIN@3Foswiki::Search::InfoCache::BEGIN@3
22128µs28µsFoswiki::Search::InfoCache::::CORE:qrFoswiki::Search::InfoCache::CORE:qr (opcode)
33119µs19µsFoswiki::Search::InfoCache::::CORE:substFoswiki::Search::InfoCache::CORE:subst (opcode)
11118µs69µsFoswiki::Search::InfoCache::::BEGIN@23Foswiki::Search::InfoCache::BEGIN@23
11116µs34µsFoswiki::Search::InfoCache::::BEGIN@4Foswiki::Search::InfoCache::BEGIN@4
11110µs10µsFoswiki::Search::InfoCache::::BEGIN@25Foswiki::Search::InfoCache::BEGIN@25
11110µs10µsFoswiki::Search::InfoCache::::BEGIN@24Foswiki::Search::InfoCache::BEGIN@24
1119µs9µsFoswiki::Search::InfoCache::::BEGIN@6Foswiki::Search::InfoCache::BEGIN@6
0000s0sFoswiki::Search::InfoCache::::_compareFoswiki::Search::InfoCache::_compare
0000s0sFoswiki::Search::InfoCache::::addTopicFoswiki::Search::InfoCache::addTopic
0000s0sFoswiki::Search::InfoCache::::filterByDateFoswiki::Search::InfoCache::filterByDate
0000s0sFoswiki::Search::InfoCache::::isImmutableFoswiki::Search::InfoCache::isImmutable
0000s0sFoswiki::Search::InfoCache::::numberOfTopicsFoswiki::Search::InfoCache::numberOfTopics
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::Search::InfoCache;
3245µs243µs
# spent 36µs (29+7) within Foswiki::Search::InfoCache::BEGIN@3 which was called: # once (29µs+7µs) by Foswiki::Search::BEGIN@19 at line 3
use strict;
# spent 36µs making 1 call to Foswiki::Search::InfoCache::BEGIN@3 # spent 7µs making 1 call to strict::import
4243µs252µs
# spent 34µs (16+18) within Foswiki::Search::InfoCache::BEGIN@4 which was called: # once (16µs+18µs) by Foswiki::Search::BEGIN@19 at line 4
use warnings;
# spent 34µs making 1 call to Foswiki::Search::InfoCache::BEGIN@4 # spent 18µs making 1 call to warnings::import
5
6278µs19µs
# spent 9µs within Foswiki::Search::InfoCache::BEGIN@6 which was called: # once (9µs+0s) by Foswiki::Search::BEGIN@19 at line 6
use Foswiki::ListIterator ();
# spent 9µs making 1 call to Foswiki::Search::InfoCache::BEGIN@6
7149µsour @ISA = ('Foswiki::ListIterator');
8
9=begin TML
10
11---+ package Foswiki::Search::InfoCache
12
13Support package; cache of topic info. When information about search hits is
14compiled for output, this cache is used to avoid recovering the same info
15about the same topic more than once.
16
17=cut
18
19# TODO: this is going to transform from an ugly duckling into the
20# ResultSet Iterator
21# Sven has the feeling that we should make result sets immutable
22
23248µs2120µs
# spent 69µs (18+51) within Foswiki::Search::InfoCache::BEGIN@23 which was called: # once (18µs+51µs) by Foswiki::Search::BEGIN@19 at line 23
use Assert;
# spent 69µs making 1 call to Foswiki::Search::InfoCache::BEGIN@23 # spent 51µs making 1 call to Assert::import
24241µs110µs
# spent 10µs within Foswiki::Search::InfoCache::BEGIN@24 which was called: # once (10µs+0s) by Foswiki::Search::BEGIN@19 at line 24
use Foswiki::Func ();
# spent 10µs making 1 call to Foswiki::Search::InfoCache::BEGIN@24
25241µs110µs
# spent 10µs within Foswiki::Search::InfoCache::BEGIN@25 which was called: # once (10µs+0s) by Foswiki::Search::BEGIN@19 at line 25
use Foswiki::Meta ();
# spent 10µs making 1 call to Foswiki::Search::InfoCache::BEGIN@25
2623.65ms11.34ms
# spent 1.34ms (1.18+155µs) within Foswiki::Search::InfoCache::BEGIN@26 which was called: # once (1.18ms+155µs) by Foswiki::Search::BEGIN@19 at line 26
use Foswiki::Iterator::FilterIterator ();
# spent 1.34ms making 1 call to Foswiki::Search::InfoCache::BEGIN@26
27
28#use Monitor ();
29#Monitor::MonitorMethod('Foswiki::Search::InfoCache', 'getTopicListIterator');
30
31=begin TML
32
33---++ ClassMethod new($session, $defaultWeb, \@topicList)
34Initialise a new list of topics, allowing their data to be lazy loaded
35if and when needed.
36
37$defaultWeb is used to qualify topics that do not have a web
38specifier - should expect it to be the same as BASEWEB in most cases.
39
40Because this Iterator can be created and filled dynamically, once the Iterator hasNext() and next() methods are called, it is immutable.
41
42=cut
43
44#TODO: duplicates??, what about topicExists?
45#TODO: remove the iterator code from this __container__ and make a $this->getIterator() which can then be used.
46#TODO: replace the Iterator->reset() function with a lightweight Iterator->copyConstructor?
47#TODO: or..... make reset() make the object mutable again, so we can change the elements in the list, but re-use the meta cache??
48#CONSIDER: convert the internals to a hash[tomAddress] = {matches->[list of resultint text bits], othermeta...} - except this does not give us order :/
49
50
# spent 99µs (67+33) within Foswiki::Search::InfoCache::new which was called: # once (67µs+33µs) by Foswiki::Store::QueryAlgorithms::BruteForce::_webQuery at line 63 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm
sub new {
51766µs my ( $class, $session, $defaultWeb, $topicList ) = @_;
52
53133µs my $this = $class->SUPER::new( [] );
# spent 33µs making 1 call to Foswiki::ListIterator::new
54 $this->{_session} = $session;
55 $this->{_defaultWeb} = $defaultWeb;
56 $this->{count} = 0;
57 if ( defined($topicList) ) {
58 $this->addTopics( $defaultWeb, @$topicList );
59 }
60
61 return $this;
62}
63
64sub isImmutable {
65 my $this = shift;
66 return ( $this->{index} != 0 );
67}
68
69
# spent 2.20ms (873µs+1.33) within Foswiki::Search::InfoCache::addTopics which was called 22 times, avg 100µs/call: # 22 times (873µs+1.33ms) by Foswiki::Store::QueryAlgorithms::BruteForce::_webQuery at line 193 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm, avg 100µs/call
sub addTopics {
70110467µs my ( $this, $defaultWeb, @list ) = @_;
712276µs ASSERT( !$this->isImmutable() )
# spent 76µs making 22 calls to Assert::ASSERTS_OFF, avg 3µs/call
72 if DEBUG; #cannot modify list once its being used as an iterator.
732268µs ASSERT( defined($defaultWeb) ) if DEBUG;
# spent 68µs making 22 calls to Assert::ASSERTS_OFF, avg 3µs/call
74
75 foreach my $t (@list) {
7666296µs221.19ms my ( $web, $topic ) =
# spent 1.19ms making 22 calls to Foswiki::Func::normalizeWebTopicName, avg 54µs/call
77 Foswiki::Func::normalizeWebTopicName( $defaultWeb, $t );
782243µs push( @{ $this->{list} }, "$web.$topic" );
79 $this->{count}++;
80 }
81 undef $this->{sorted};
82}
83
84#TODO: what if it isa Meta obj
85#TODO: or an infoCache obj..
86sub addTopic {
87 my ( $this, $meta ) = @_;
88 ASSERT( !$this->isImmutable() )
89 if DEBUG; #cannot modify list once its being used as an iterator.
90
91 my $web = $meta->web();
92 my $topic = $meta->topic();
93
94 my ( $w, $t ) = Foswiki::Func::normalizeWebTopicName( $web, $topic );
95 my $webtopic = "$w.$t";
96 push( @{ $this->{list} }, $webtopic );
97 $this->{count}++;
98 if ( defined($meta) ) {
99 $this->{_session}->search->metacache->addMeta( $web, $topic, $meta );
100 }
101 undef $this->{sorted};
102}
103
104sub numberOfTopics {
105 my $this = shift;
106
107 #can't use this, as it lies once its gone through the 'sortResults' hack
108 #return scalar(@{ $this->{list} });
109 # when fixed, the count update in filterByDate should be removed
110
111 return $this->{count};
112}
113
114=begin TML
115
116---++ ObjectMethod sortResults($params)
117
118the implementation of %SORT{"" limit="" order="" reverse="" date=""}%
119
120it should be possible for the search engine to pre-sort, making this a nop, or to
121delay evaluated, partially evaluated, or even delegated to the DB/SQL
122
123can call repeatedly, the list will only be re-sorted if new elements are added.
124
125=cut
126
127
# spent 753µs (183+570) within Foswiki::Search::InfoCache::sortResults which was called 2 times, avg 376µs/call: # once (177µs+570µs) by Foswiki::Store::Interfaces::QueryAlgorithm::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/Interfaces/QueryAlgorithm.pm:109] at line 106 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/Interfaces/QueryAlgorithm.pm # once (7µs+0s) by Foswiki::Search::ResultSet::sortResults at line 266 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Search/ResultSet.pm
sub sortResults {
1281493µs my ( $this, $params ) = @_;
129
130 #TODO: for now assume we do not change the sort order later
131 return if ( defined( $this->{sorted} ) );
132 $this->{sorted} = 1;
133
134 my $session = $this->{_session};
135
136 my $sortOrder = $params->{order} || '';
137117µs my $revSort = Foswiki::isTrue( $params->{reverse} );
# spent 17µs making 1 call to Foswiki::isTrue
138 my $limit = $params->{limit} || '';
139
140 #SMELL: duplicated code - removeme
141 # Limit search results
14212µs12µs if ( $limit =~ /(^\d+$)/o ) {
# spent 2µs making 1 call to Foswiki::Search::InfoCache::CORE:match
143
144 # only digits, all else is the same as
145 # an empty string. "+10" won't work.
146 $limit = $1;
147 }
148 else {
149
150 # change 'all' to 0, then to big number
151 $limit = 0;
152 }
153 $limit = 32000 unless ($limit);
154
155 # TODO: this is really an ugly hack to get around the rather
156 # horrible limit 'performance' hack
157 if ( defined( $params->{showpage} )
158 and $params->{showpage} > 1 )
159 {
160 $limit = ( 2 + $params->{showpage} ) * $params->{pagesize};
161 }
162
163 # sort the topic list by date, author or topic name, and cache the
164 # info extracted to do the sorting
16512µs23µs if ( $sortOrder eq 'modified' ) {
# spent 2µs making 1 call to Foswiki::Search::InfoCache::CORE:match # spent 1µs making 1 call to Foswiki::Search::InfoCache::CORE:subst
166
167 # For performance:
168 # * sort by approx time (to get a rough list)
169 # * shorten list to the limit + some slack
170 # * sort by rev date on shortened list to get the accurate list
171 # SMELL: Cairo had efficient two stage handling of modified sort.
172 # SMELL: In Dakar this seems to be pointless since latest rev
173 # time is taken from topic instead of dir list.
174 my $slack = 10;
175 if ( $limit + 2 * $slack < scalar( @{ $this->{list} } ) ) {
176
177 # sort by approx latest rev time
178 my @tmpList =
179 map { $_->[1] }
180 sort { $a->[0] <=> $b->[0] }
181 map {
182 my ( $web, $topic ) =
183 Foswiki::Func::normalizeWebTopicName( $this->{_defaultWeb},
184 $_ );
185 [ $session->getApproxRevTime( $web, $topic ), $_ ]
186 } @{ $this->{list} };
187 @tmpList = reverse(@tmpList) if ($revSort);
188
189 # then shorten list and build the hashes for date and author
190 my $idx = $limit + $slack;
191 @{ $this->{list} } = ();
192 foreach (@tmpList) {
193 push( @{ $this->{list} }, $_ );
194 $idx -= 1;
195 last if $idx <= 0;
196 }
197 }
198
199 }
200 elsif (
201 $sortOrder =~ /^creat/ || # topic creation time
202 $sortOrder eq 'editby' || # author
203 $sortOrder =~ s/^formfield\(([^\)]+)\)$/$1/ # form field
204 )
205 {
206 }
207 else {
208
209 #default to topic sorting
210 $sortOrder = 'topic';
211 }
2121548µs sortTopics( $this->{list}, $sortOrder, !$revSort );
# spent 548µs making 1 call to Foswiki::Search::InfoCache::sortTopics
213}
214
215=begin TML
216
217---++ filterByDate( $date )
218
219Filter the list by date interval; see System.TimeSpecifications.
220
221<verbatim>
222$infoCache->filterByDate( $date );
223</verbatim>
224
225=cut
226
227sub filterByDate {
228 my ( $this, $date ) = @_;
229
230 my $session = $Foswiki::Plugins::SESSION;
231
232 require Foswiki::Time;
233 my @ends = Foswiki::Time::parseInterval($date);
234 my @resultList = ();
235 foreach my $webtopic ( @{ $this->{list} } ) {
236
237 # if date falls out of interval: exclude topic from result
238 my ( $web, $topic ) =
239 Foswiki::Func::normalizeWebTopicName( $this->{_defaultWeb},
240 $webtopic );
241 my $topicdate = $session->getApproxRevTime( $web, $topic );
242 push( @resultList, $webtopic )
243 unless ( $topicdate < $ends[0] || $topicdate > $ends[1] );
244 }
245 $this->{list} = \@resultList;
246
247 # use this hack until numberOfTopics reads the length of list
248 $this->{count} = length @{ $this->{list} };
249}
250
251######OLD methods
252
253# Sort a topic list using cached info
254
# spent 548µs (374+174) within Foswiki::Search::InfoCache::sortTopics which was called: # once (374µs+174µs) by Foswiki::Search::InfoCache::sortResults at line 212
sub sortTopics {
255415µs my ( $listRef, $sortfield, $revSort ) = @_;
25615µs ASSERT($sortfield);
# spent 5µs making 1 call to Assert::dummyASSERT
257
258 # don't spend time doing stuff to an empty list (or a list of one!)
259 return if ( scalar(@$listRef) < 2 );
260
2613120µs if ( $sortfield eq 'topic' ) {
262
263 # simple sort
264 # note no extraction of topic info here, as not needed
265 # for the sort. Instead it will be read lazily, later on.
266 # TODO: need to remove the web portion
267 # mmm, need to profile if there is even a point to this -
268 # as all topics still need to be parsed to find permissions
26922161µs if ($revSort) {
270 @{$listRef} = map { $_->[1] }
27122104µs sort { $a->[0] cmp $b->[0] }
# spent 104µs making 22 calls to Foswiki::Search::InfoCache::CORE:match, avg 5µs/call
272 map { $_ =~ /^(.*?)([^.]+)$/; [ $2, $_ ] } #quickhack to remove web
27368324µs161µs @{$listRef};
# spent 61µs making 1 call to Foswiki::Search::InfoCache::CORE:sort
274 }
275 else {
276 @{$listRef} = map { $_->[1] }
277 sort { $b->[0] cmp $a->[0] }
278 map { $_ =~ /^(.*?)([^.]+)$/; [ $2, $_ ] } #quickhack to remove web
279 @{$listRef};
280 }
28114µs ASSERT( $listRef->[0] ) if DEBUG;
# spent 4µs making 1 call to Assert::ASSERTS_OFF
282 return;
283 }
284
285 my $metacache = $Foswiki::Plugins::SESSION->search->metacache;
286
287 # populate the cache for each topic
288 foreach my $webtopic ( @{$listRef} ) {
289
290 my $info = $metacache->get($webtopic);
291
292 if ( $sortfield =~ /^creat/ ) {
293
294 # The act of getting the info will cache it
295 #$metacache->getRev1Info( $webtopic, $sortfield );
296 $info->{$sortfield} = $info->{tom}->getRev1Info($sortfield);
297 }
298 else {
299
300 # SMELL: SD duplicated from above - I'd rather do it only here,
301 # but i'm not sure if i can.
302 $sortfield =~ s/^formfield\((.*)\)$/$1/; # form field
303
304 if ( !defined( $info->{$sortfield} ) ) {
305
306#under normal circumstances this code is not called, because the metacach has already filled it.
307 if ( $sortfield eq 'modified' ) {
308 my $ri = $info->{tom}->getRevisionInfo();
309 $info->{$sortfield} = $ri->{date};
310 }
311 else {
312 $info->{$sortfield} =
313 Foswiki::Search::displayFormField( $info->{tom},
314 $sortfield );
315 }
316 }
317 }
318
319 # SMELL: CDot isn't clear why this is needed, but it is otherwise
320 # we end up with the users all being identified as "undef"
321 $info->{editby} =
322 $info->{tom}->session->{users}->getWikiName( $info->{editby} );
323 }
324 if ($revSort) {
325 @{$listRef} = map { $_->[1] }
326 sort { _compare( $b->[0], $a->[0] ) }
327 map { [ $metacache->get($_)->{$sortfield}, $_ ] } @{$listRef};
328 }
329 else {
330 @{$listRef} = map { $_->[1] }
331 sort { _compare( $a->[0], $b->[0] ) }
332 map { [ $metacache->get($_)->{$sortfield}, $_ ] } @{$listRef};
333 }
334}
335
336# RE for a full-spec floating-point number
337135µs119µsour $NUMBER = qr/^[-+]?[0-9]+(\.[0-9]*)?([Ee][-+]?[0-9]+)?$/s;
# spent 19µs making 1 call to Foswiki::Search::InfoCache::CORE:qr
338
339sub _compare {
340 my $x = shift;
341 my $y = shift;
342
343 ASSERT( defined($x) ) if DEBUG;
344 ASSERT( defined($y) ) if DEBUG;
345
346 if ( $x =~ /$NUMBER/o && $y =~ /$NUMBER/o ) {
347
348 # when sorting numbers do it largest first; this is just because
349 # this is what date comparisons need.
350 return $y <=> $x;
351 }
352
353 my $datex = undef;
354 my $datey = undef;
355
356 # parseTime can error if you give it a date out of range so we skip
357 # testing if pure number
358 # We skip testing for dates the first character is not a digit
359 # as all formats we recognise as dates are
360 if ( $x =~ /^\d/
361 && $x !~ /$NUMBER/o
362 && $y =~ /^\d/
363 && $y !~ /$NUMBER/o )
364 {
365 $datex = Foswiki::Time::parseTime($x);
366 $datey = Foswiki::Time::parseTime($y) if $datex;
367 }
368
369 if ( $datex && $datey ) {
370 return $datey <=> $datex;
371 }
372 else {
373 return $y cmp $x;
374 }
375}
376
377=begin TML
378
379---++ StaticMethod getOptionFilter(\%options) -> $code
380
381Analyse the options given in \%options and return a function that
382filters based on those options. \%options may include:
383 * =includeTopics= - a comma-separated wildcard list of topic names
384 * =excludeTopics= - do
385 * =casesensitive= - boolean
386
387=cut
388
389
# spent 209µs (69+140) within Foswiki::Search::InfoCache::getOptionFilter which was called: # once (69µs+140µs) by Foswiki::Search::InfoCache::getTopicListIterator at line 459
sub getOptionFilter {
390841µs my ($options) = @_;
391
392 my $casesensitive =
393 defined( $options->{casesensitive} ) ? $options->{casesensitive} : 1;
394
395 # E.g. "Web*, FooBar" ==> "^(Web.*|FooBar)$"
396 my $includeTopics;
397 my $topicFilter;
398 my $excludeTopics;
399 $excludeTopics = convertTopicPatternToRegex( $options->{excludeTopics} )
400 if ( $options->{excludeTopics} );
401
402212µs if ( $options->{includeTopics} ) {
403
404 # E.g. "Bug*, *Patch" ==> "^(Bug.*|.*Patch)$"
4051115µs $includeTopics =
406 convertTopicPatternToRegex( $options->{includeTopics} );
407
408140µs if ($casesensitive) {
409 $topicFilter = qr/$includeTopics/;
410 }
411 else {
412225µs $topicFilter = qr/$includeTopics/i;
# spent 16µs making 1 call to Foswiki::Search::InfoCache::CORE:regcomp # spent 9µs making 1 call to Foswiki::Search::InfoCache::CORE:qr
413 }
414 }
415
416
# spent 63.8ms (45.5+18.3) within Foswiki::Search::InfoCache::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Search/InfoCache.pm:424] which was called 3425 times, avg 19µs/call: # 3425 times (45.5ms+18.3ms) by Foswiki::Iterator::FilterIterator::hasNext at line 66 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Iterator/FilterIterator.pm, avg 19µs/call
return sub {
417689468.1ms my $item = shift;
418685018.3ms return 0 unless !$topicFilter || $item =~ /$topicFilter/;
# spent 11.0ms making 3425 calls to Foswiki::Search::InfoCache::CORE:match, avg 3µs/call # spent 7.28ms making 3425 calls to Foswiki::Search::InfoCache::CORE:regcomp, avg 2µs/call
419 if ( defined $excludeTopics ) {
420 return 0 if $item =~ /$excludeTopics/;
421 return 0 if !$casesensitive && $item =~ /$excludeTopics/i;
422 }
423 return 1;
424 }
425}
426
427#########################################
428# TODO: this is _now_ a default utility method that can be used by
429# search&query algo's to brute force file a list of topics to search.
430# if you can avoid it, you should - as it needs to do an opendir on the
431# web, and if you have alot of topics, life gets slow
432# get a list of topics to search in the web, filtered by the $topic
433# spec
434
# spent 170ms (67µs+170) within Foswiki::Search::InfoCache::getTopicListIterator which was called: # once (67µs+170ms) by Foswiki::Store::QueryAlgorithms::BruteForce::_webQuery at line 134 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm
sub getTopicListIterator {
435550µs my ( $webObject, $options ) = @_;
436
437 my $casesensitive =
438 defined( $options->{casesensitive} ) ? $options->{casesensitive} : 1;
439
440 # See if there's a list of topics to avoid having to do a web list
441 my $it;
442110µs if ( $casesensitive
443 && $options->{includeTopics}
444 && $options->{includeTopics} =~
445 /^([$Foswiki::regex{mixedAlphaNum}]+(,\s*|\|))+$/ )
446 {
447
448 # topic list without wildcards
449 # convert pattern into a topic list
450 my @list = grep {
451 $Foswiki::Plugins::SESSION->topicExists( $webObject->web, $_ )
452 } split( /,\s*|\|/, $options->{includeTopics} );
453 $it = new Foswiki::ListIterator( \@list );
454 }
455 else {
4561170ms $it = $webObject->eachTopic();
# spent 170ms making 1 call to Foswiki::Meta::eachTopic
457 }
458
4592261µs return Foswiki::Iterator::FilterIterator->new( $it,
# spent 209µs making 1 call to Foswiki::Search::InfoCache::getOptionFilter # spent 52µs making 1 call to Foswiki::Iterator::FilterIterator::new
460 getOptionFilter($options) );
461}
462
463
# spent 115µs (65+50) within Foswiki::Search::InfoCache::convertTopicPatternToRegex which was called: # once (65µs+50µs) by Foswiki::Search::InfoCache::getOptionFilter at line 405
sub convertTopicPatternToRegex {
464532µs my ($topic) = @_;
465 return '' unless ($topic);
466
467 # 'Web*, FooBar' ==> ( 'Web*', 'FooBar' ) ==> ( 'Web.*', "FooBar" )
468239µs my @arr =
# spent 33µs making 1 call to Foswiki::Search::InfoCache::CORE:regcomp # spent 6µs making 1 call to Foswiki::Search::InfoCache::CORE:subst
469388µs111µs map { s/[^\*\_\-\+$Foswiki::regex{mixedAlphaNum}]//go; s/\*/\.\*/go; $_ }
# spent 11µs making 1 call to Foswiki::Search::InfoCache::CORE:subst
470 split( /(?:,\s*|\|)/, $topic );
471 return '' unless (@arr);
472
473 # ( 'Web.*', 'FooBar' ) ==> "^(Web.*|FooBar)$"
474 return '^(' . join( '|', @arr ) . ')$';
475}
476
477111µs1;
478__END__
 
# spent 11.1ms within Foswiki::Search::InfoCache::CORE:match which was called 3449 times, avg 3µs/call: # 3425 times (11.0ms+0s) by Foswiki::Search::InfoCache::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Search/InfoCache.pm:424] at line 418, avg 3µs/call # 22 times (104µs+0s) by Foswiki::Search::InfoCache::sortTopics at line 271, avg 5µs/call # once (2µs+0s) by Foswiki::Search::InfoCache::sortResults at line 142 # once (2µs+0s) by Foswiki::Search::InfoCache::sortResults at line 165
sub Foswiki::Search::InfoCache::CORE:match; # opcode
# spent 28µs within Foswiki::Search::InfoCache::CORE:qr which was called 2 times, avg 14µs/call: # once (19µs+0s) by Foswiki::Search::BEGIN@19 at line 337 # once (9µs+0s) by Foswiki::Search::InfoCache::getOptionFilter at line 412
sub Foswiki::Search::InfoCache::CORE:qr; # opcode
# spent 7.33ms within Foswiki::Search::InfoCache::CORE:regcomp which was called 3427 times, avg 2µs/call: # 3425 times (7.28ms+0s) by Foswiki::Search::InfoCache::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Search/InfoCache.pm:424] at line 418, avg 2µs/call # once (33µs+0s) by Foswiki::Search::InfoCache::convertTopicPatternToRegex at line 468 # once (16µs+0s) by Foswiki::Search::InfoCache::getOptionFilter at line 412
sub Foswiki::Search::InfoCache::CORE:regcomp; # opcode
# spent 61µs within Foswiki::Search::InfoCache::CORE:sort which was called: # once (61µs+0s) by Foswiki::Search::InfoCache::sortTopics at line 273
sub Foswiki::Search::InfoCache::CORE:sort; # opcode
# spent 19µs within Foswiki::Search::InfoCache::CORE:subst which was called 3 times, avg 6µs/call: # once (11µs+0s) by Foswiki::Search::InfoCache::convertTopicPatternToRegex at line 469 # once (6µs+0s) by Foswiki::Search::InfoCache::convertTopicPatternToRegex at line 468 # once (1µs+0s) by Foswiki::Search::InfoCache::sortResults at line 165
sub Foswiki::Search::InfoCache::CORE:subst; # opcode