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

Filename/var/www/foswikidev/core/lib/Foswiki/Search/ResultSet.pm
StatementsExecuted 281613 statements in 304ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
3512022239ms431msFoswiki::Search::ResultSet::::hasNextFoswiki::Search::ResultSet::hasNext
175201181.6ms98.1msFoswiki::Search::ResultSet::::nextFoswiki::Search::ResultSet::next
80111.53ms1.53msFoswiki::Search::ResultSet::::newFoswiki::Search::ResultSet::new
80111.08ms182msFoswiki::Search::ResultSet::::sortResultsFoswiki::Search::ResultSet::sortResults
11115µs29µsFoswiki::Search::ResultSet::::BEGIN@17Foswiki::Search::ResultSet::BEGIN@17
11110µs14µsFoswiki::Search::ResultSet::::BEGIN@18Foswiki::Search::ResultSet::BEGIN@18
1119µs35µsFoswiki::Search::ResultSet::::BEGIN@24Foswiki::Search::ResultSet::BEGIN@24
1119µs9µsFoswiki::Search::ResultSet::::BEGIN@23Foswiki::Search::ResultSet::BEGIN@23
1114µs4µsFoswiki::Search::ResultSet::::BEGIN@20Foswiki::Search::ResultSet::BEGIN@20
1114µs4µsFoswiki::Search::ResultSet::::BEGIN@26Foswiki::Search::ResultSet::BEGIN@26
0000s0sFoswiki::Search::ResultSet::::filterByDateFoswiki::Search::ResultSet::filterByDate
0000s0sFoswiki::Search::ResultSet::::nextWebFoswiki::Search::ResultSet::nextWeb
0000s0sFoswiki::Search::ResultSet::::numberOfTopicsFoswiki::Search::ResultSet::numberOfTopics
0000s0sFoswiki::Search::ResultSet::::skipFoswiki::Search::ResultSet::skip
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::Search::ResultSet
6
7This class implements the ResultSet API - its basically a Sorted Aggregate Iterator for foswiki 1.1
8 * NOTE: does not implement the unique function - by its nature, the data is unique, and it would be a non-trivial drain on memory in this context
9
10(due to the partially completed InfoCache removeal)
11
12in future it will probably become more clever.
13
14=cut
15
16package Foswiki::Search::ResultSet;
17228µs242µs
# spent 29µs (15+14) within Foswiki::Search::ResultSet::BEGIN@17 which was called: # once (15µs+14µs) by Foswiki::Search::BEGIN@20 at line 17
use strict;
# spent 29µs making 1 call to Foswiki::Search::ResultSet::BEGIN@17 # spent 14µs making 1 call to strict::import
18225µs219µs
# spent 14µs (10+4) within Foswiki::Search::ResultSet::BEGIN@18 which was called: # once (10µs+4µs) by Foswiki::Search::BEGIN@20 at line 18
use warnings;
# spent 14µs making 1 call to Foswiki::Search::ResultSet::BEGIN@18 # spent 4µs making 1 call to warnings::import
19
20234µs14µs
# spent 4µs within Foswiki::Search::ResultSet::BEGIN@20 which was called: # once (4µs+0s) by Foswiki::Search::BEGIN@20 at line 20
use Foswiki::Iterator ();
# spent 4µs making 1 call to Foswiki::Search::ResultSet::BEGIN@20
2117µsour @ISA = ('Foswiki::Iterator');
22
23226µs19µs
# spent 9µs within Foswiki::Search::ResultSet::BEGIN@23 which was called: # once (9µs+0s) by Foswiki::Search::BEGIN@20 at line 23
use Foswiki::Search::InfoCache;
# spent 9µs making 1 call to Foswiki::Search::ResultSet::BEGIN@23
24253µs261µs
# spent 35µs (9+26) within Foswiki::Search::ResultSet::BEGIN@24 which was called: # once (9µs+26µs) by Foswiki::Search::BEGIN@20 at line 24
use Assert;
# spent 35µs making 1 call to Foswiki::Search::ResultSet::BEGIN@24 # spent 26µs making 1 call to Exporter::import
25
26
# spent 4µs within Foswiki::Search::ResultSet::BEGIN@26 which was called: # once (4µs+0s) by Foswiki::Search::BEGIN@20 at line 31
BEGIN {
2715µs if ( $Foswiki::cfg{UseLocale} ) {
28 require locale;
29 import locale();
30 }
311790µs14µs}
# spent 4µs making 1 call to Foswiki::Search::ResultSet::BEGIN@26
32
33=begin TML
34
35---++ new(\@list)
36
37Create a new iterator over the given list of iterators. The list is
38not damaged in any way.
39
40=cut
41
42
# spent 1.53ms within Foswiki::Search::ResultSet::new which was called 80 times, avg 19µs/call: # 80 times (1.53ms+0s) by Foswiki::Store::Interfaces::QueryAlgorithm::query at line 132 of /var/www/foswikidev/core/lib/Foswiki/Store/Interfaces/QueryAlgorithm.pm, avg 19µs/call
sub new {
4380254µs my ( $class, $list, $partition, $sortby, $revSort ) = @_;
44
4580940µs my $this = bless(
46 {
47 Itr_list => $list,
48 Itr_index => 0,
49 next => undef,
50 Itr_next => [],
51 partition => $partition || 'web',
52 sortby => $sortby || 'topic',
53 revsort => $revSort || 0,
54 },
55 $class
56 );
57
5880394µs return $this;
59}
60
61sub numberOfTopics {
62 my $this = shift;
63
64 return $this->{count} if ( defined( $this->{count} ) );
65
66 my $count = 0;
67 foreach my $infocache ( @{ $this->{Itr_list} } ) {
68 $count += $infocache->numberOfTopics();
69 }
70 $this->{count} = $count;
71
72 return $count;
73}
74
75=begin TML
76
77---++ hasNext() -> $boolean
78
79Returns false when the iterator is exhausted.
80
81=cut
82
83
# spent 431ms (239+191) within Foswiki::Search::ResultSet::hasNext which was called 35120 times, avg 12µs/call: # 17600 times (223ms+191ms) by Foswiki::Iterator::FilterIterator::hasNext at line 71 of /var/www/foswikidev/core/lib/Foswiki/Iterator/FilterIterator.pm, avg 24µs/call # 17520 times (16.5ms+0s) by Foswiki::Search::ResultSet::next at line 235, avg 940ns/call
sub hasNext {
843512011.7ms my ($this) = @_;
853512054.3ms return 1 if $this->{next};
86
87#this is the 'normal' legacy way to iterate over the list of results (one web at a time)
88176008.34ms if (
89 ( $this->{partition} eq 'web' )
90 or (
91 scalar( @{ $this->{Itr_list} } ) <= 0
92 ) #no reason to got through the more complex case if there's only one itr
93 )
94 {
95176001.94ms my $n;
961760014.8ms do {
97176804.73ms unless ( $this->{list} ) {
98 if ( $this->{Itr_index} < scalar( @{ $this->{Itr_list} } ) ) {
99 $this->{list} = $this->{Itr_list}->[ $this->{Itr_index}++ ];
100 }
101 else {
10280174µs return 0; #no more iterators in list
103 }
104 }
1051760048.2ms35120191ms if ( $this->{list}->hasNext() ) {
# spent 119ms making 17520 calls to Foswiki::ListIterator::next, avg 7µs/call # spent 72.7ms making 17600 calls to Foswiki::ListIterator::hasNext, avg 4µs/call
106 $n = $this->{list}->next();
107 }
108 else {
1098056µs $this->{list} = undef; #goto next iterator
110 }
111 } while ( !$this->{list} );
112175206.92ms $this->{next} = $n;
113 }
114 else {
115
116#yes, this is innefficient, for now I'm looking only to get a functioning result.
117 my $next = -1;
118 for ( my $idx = 0 ; $idx < scalar( @{ $this->{Itr_list} } ) ; $idx++ ) {
119
120 #load the next element from each of the iterators
121 if ( !defined( $this->{Itr_next}[$idx] )
122 and $this->{Itr_list}[$idx]->hasNext() )
123 {
124 $this->{Itr_next}[$idx] = $this->{Itr_list}[$idx]->next();
125 }
126 if ( defined( $this->{Itr_next}[$idx] ) ) {
127
128 #find the first one of them (works because each iterator is already sorted..
129 if ( $next == -1 ) {
130 $next = $idx;
131 next;
132 }
133
134 #print STDERR "------ trying ($idx) ".$this->{Itr_next}[$idx]."\n";
135 #compare $next's elem with $idx's and rotate if needed
136 my @two = ( $this->{Itr_next}[$next], $this->{Itr_next}[$idx] );
137 Foswiki::Search::InfoCache::sortTopics( \@two, $this->{sortby},
138 !$this->{revsort} );
139 if ( $two[0] ne $this->{Itr_next}[$next] ) {
140 $next = $idx;
141 }
142 }
143 }
144
145 #print STDERR "---getting result from $next\n";
146 if ( $next == -1 ) {
147 return 0;
148 }
149 else {
150 $this->{next} = $this->{Itr_next}[$next];
151 $this->{Itr_next}[$next] = undef;
152 }
153
154 }
1551752060.2ms return 1;
156}
157
158=begin TML
159
160---++ skip(count) -> $countremaining
161
162skip X elements (returns 0 if successful, or number of elements remaining to skip if there are not enough elements to skip)
163skip must set up next as though hasNext was called.
164
165=cut
166
167sub skip {
168 my $this = shift;
169 my $count = shift;
170
171 return 0 if ( $count <= 0 );
172 print STDERR
173 "--------------------------------------------ResultSet::skip($count)\n"
174 if Foswiki::Iterator::MONITOR;
175
176 #ask CAN skip() for faster path
177 if (
178 (
179 ( $this->{partition} eq 'web' )
180 or ( scalar( @{ $this->{Itr_list} } ) == 0 )
181 )
182 and #no reason to got through the more complex case if there's only one itr
183 ( $this->{Itr_list}->[0]->can('skip')
184 ) #nasty assumption that all the itr's are a similar type (that happens to be true)
185 )
186 {
187 if ( not defined( $this->{list} ) ) {
188 $this->{list} = $this->{Itr_list}->[ $this->{Itr_index}++ ];
189 }
190 while ( $count > 0 ) {
191 return $count if ( not defined( $this->{list} ) );
192 $count = $this->{list}->skip($count);
193 $this->{next} = $this->{list}->{next};
194 if ( $count > 0 ) {
195 $this->{list} = $this->{Itr_list}->[ $this->{Itr_index}++ ];
196 $this->{next} = undef;
197 }
198 }
199 }
200 else {
201
202 #brute force -
203 while (
204 ( $count > 0
205 ) #must come first - don't want to advance the inner itr if count ==0
206 and $this->hasNext()
207 )
208 {
209 $count--;
210 $this->next(); #drain next, so hasNext goes to next element
211 }
212 }
213
214 if ( $count >= 0 ) {
215
216 #skipped past the end of the set
217 $this->{next} = undef;
218 }
219 print STDERR
220"--------------------------------------------ResultSet::skip() => $count\n"
221 if Foswiki::Iterator::MONITOR;
222 return $count;
223}
224
225=begin TML
226
227---++ next() -> $data
228
229Return the next entry in the list.
230
231=cut
232
233
# spent 98.1ms (81.6+16.5) within Foswiki::Search::ResultSet::next which was called 17520 times, avg 6µs/call: # 17520 times (81.6ms+16.5ms) by Foswiki::Iterator::FilterIterator::hasNext at line 72 of /var/www/foswikidev/core/lib/Foswiki/Iterator/FilterIterator.pm, avg 6µs/call
sub next {
234175203.48ms my $this = shift;
2351752012.3ms1752016.5ms $this->hasNext();
# spent 16.5ms making 17520 calls to Foswiki::Search::ResultSet::hasNext, avg 940ns/call
236175205.45ms my $n = $this->{next};
237175203.92ms $this->{next} = undef;
238
2391752064.2ms return $n;
240}
241
242=begin TML
243
244---++ nextWeb() -> $data
245
246switch tot he next Web (only works on partition==web, and if we've already started iterating.
247=cut
248
249sub nextWeb {
250 my $this = shift;
251
252 ASSERT( $this->{partition} eq 'web' ) if DEBUG;
253 ASSERT( $this->{list} ) if DEBUG;
254
255 $this->{list} = undef;
256 $this->hasNext();
257}
258
259=begin TML
260---++ sortResults
261
262the implementation of %SORT{"" limit="" order="" reverse="" date=""}%
263
264it should be possible for the search engine to pre-sort, making this a nop, or to
265delay evaluated, partially evaluated, or even delegated to the DB/SQL
266
267=cut
268
269
# spent 182ms (1.08+181) within Foswiki::Search::ResultSet::sortResults which was called 80 times, avg 2.27ms/call: # 80 times (1.08ms+181ms) by Foswiki::Iterator::FilterIterator::sortResults at line 64 of /var/www/foswikidev/core/lib/Foswiki/Iterator/FilterIterator.pm, avg 2.27ms/call
sub sortResults {
2708086µs my ( $this, $params ) = @_;
271
27280473µs foreach my $infocache ( @{ $this->{Itr_list} } ) {
27380404µs80181ms $infocache->sortResults($params);
# spent 181ms making 80 calls to Foswiki::Search::InfoCache::sortResults, avg 2.26ms/call
274 }
275}
276
277sub filterByDate {
278 my ( $this, $date ) = @_;
279
280 foreach my $infocache ( @{ $this->{Itr_list} } ) {
281 $infocache->filterByDate($date);
282 }
283}
284
28513µs1;
286__END__