Filename | /var/www/foswiki11/lib/Foswiki/Search/ResultSet.pm |
Statements | Executed 283070 statements in 346ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
35332 | 6 | 3 | 251ms | 449ms | hasNext | Foswiki::Search::ResultSet::
17605 | 2 | 2 | 112ms | 130ms | next | Foswiki::Search::ResultSet::
81 | 2 | 2 | 1.25ms | 1.25ms | new | Foswiki::Search::ResultSet::
81 | 2 | 2 | 1.02ms | 54.9ms | sortResults | Foswiki::Search::ResultSet::
1 | 1 | 1 | 15µs | 29µs | BEGIN@17 | Foswiki::Search::ResultSet::
1 | 1 | 1 | 9µs | 14µs | BEGIN@18 | Foswiki::Search::ResultSet::
1 | 1 | 1 | 9µs | 22µs | BEGIN@24 | Foswiki::Search::ResultSet::
1 | 1 | 1 | 9µs | 9µs | BEGIN@23 | Foswiki::Search::ResultSet::
1 | 1 | 1 | 4µs | 4µs | BEGIN@20 | Foswiki::Search::ResultSet::
0 | 0 | 0 | 0s | 0s | filterByDate | Foswiki::Search::ResultSet::
0 | 0 | 0 | 0s | 0s | nextWeb | Foswiki::Search::ResultSet::
0 | 0 | 0 | 0s | 0s | numberOfTopics | Foswiki::Search::ResultSet::
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 | |||||
7 | This 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 | |||||
12 | in future it will probably become more clever. | ||||
13 | |||||
14 | =cut | ||||
15 | |||||
16 | package Foswiki::Search::ResultSet; | ||||
17 | 2 | 32µs | 2 | 43µ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 # spent 29µs making 1 call to Foswiki::Search::ResultSet::BEGIN@17
# spent 14µs making 1 call to strict::import |
18 | 2 | 25µs | 2 | 20µs | # spent 14µs (9+5) within Foswiki::Search::ResultSet::BEGIN@18 which was called:
# once (9µs+5µs) by Foswiki::Search::BEGIN@20 at line 18 # spent 14µs making 1 call to Foswiki::Search::ResultSet::BEGIN@18
# spent 5µs making 1 call to warnings::import |
19 | |||||
20 | 2 | 32µs | 1 | 4µ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 # spent 4µs making 1 call to Foswiki::Search::ResultSet::BEGIN@20 |
21 | 1 | 9µs | our @ISA = ('Foswiki::Iterator'); | ||
22 | |||||
23 | 2 | 33µs | 1 | 9µ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 # spent 9µs making 1 call to Foswiki::Search::ResultSet::BEGIN@23 |
24 | 2 | 561µs | 2 | 36µs | # spent 22µs (9+14) within Foswiki::Search::ResultSet::BEGIN@24 which was called:
# once (9µs+14µs) by Foswiki::Search::BEGIN@20 at line 24 # spent 22µs making 1 call to Foswiki::Search::ResultSet::BEGIN@24
# spent 14µs making 1 call to Assert::import |
25 | |||||
26 | =begin TML | ||||
27 | |||||
28 | ---++ new(\@list) | ||||
29 | |||||
30 | Create a new iterator over the given list of iterators. The list is | ||||
31 | not damaged in any way. | ||||
32 | |||||
33 | =cut | ||||
34 | |||||
35 | # spent 1.25ms within Foswiki::Search::ResultSet::new which was called 81 times, avg 15µs/call:
# 41 times (271µs+0s) by Foswiki::Store::QueryAlgorithms::BruteForce::query at line 82 of /var/www/foswiki11/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm, avg 7µs/call
# 40 times (983µs+0s) by Foswiki::Store::SearchAlgorithms::Forking::query at line 187 of /var/www/foswiki11/lib/Foswiki/Store/SearchAlgorithms/Forking.pm, avg 25µs/call | ||||
36 | 81 | 216µs | my ( $class, $list, $partition, $sortby, $revSort ) = @_; | ||
37 | 81 | 722µs | my $this = bless( | ||
38 | { | ||||
39 | Itr_list => $list, | ||||
40 | Itr_index => 0, | ||||
41 | next => undef, | ||||
42 | Itr_next => [], | ||||
43 | partition => $partition || 'web', | ||||
44 | sortby => $sortby || 'topic', | ||||
45 | revsort => $revSort || 0, | ||||
46 | }, | ||||
47 | $class | ||||
48 | ); | ||||
49 | 81 | 396µs | return $this; | ||
50 | } | ||||
51 | |||||
52 | sub numberOfTopics { | ||||
53 | my $this = shift; | ||||
54 | |||||
55 | my $count = 0; | ||||
56 | foreach my $infocache ( @{ $this->{Itr_list} } ) { | ||||
57 | $count += $infocache->numberOfTopics(); | ||||
58 | } | ||||
59 | |||||
60 | return $count; | ||||
61 | } | ||||
62 | |||||
63 | =begin TML | ||||
64 | |||||
65 | ---++ hasNext() -> $boolean | ||||
66 | |||||
67 | Returns false when the iterator is exhausted. | ||||
68 | |||||
69 | =cut | ||||
70 | |||||
71 | # spent 449ms (251+198) within Foswiki::Search::ResultSet::hasNext which was called 35332 times, avg 13µs/call:
# 17605 times (18.5ms+0s) by Foswiki::Search::ResultSet::next at line 156, avg 1µs/call
# 8845 times (96.5ms+94.7ms) by Foswiki::Search::formatResults at line 1032 of /var/www/foswiki11/lib/Foswiki/Search.pm, avg 22µs/call
# 8760 times (134ms+102ms) by Foswiki::Store::QueryAlgorithms::BruteForce::_webQuery at line 215 of /var/www/foswiki11/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm, avg 27µs/call
# 41 times (476µs+403µs) by Foswiki::Search::searchWeb at line 363 of /var/www/foswiki11/lib/Foswiki/Search.pm, avg 21µs/call
# 41 times (65µs+0s) by Foswiki::Search::formatResults at line 756 of /var/www/foswiki11/lib/Foswiki/Search.pm, avg 2µs/call
# 40 times (1.37ms+1.20ms) by Foswiki::Store::QueryAlgorithms::BruteForce::_webQuery at line 209 of /var/www/foswiki11/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm, avg 64µs/call | ||||
72 | 35332 | 12.3ms | my ($this) = @_; | ||
73 | 35332 | 75.8ms | return 1 if $this->{next}; | ||
74 | |||||
75 | #this is the 'normal' legacy way to iterate over the list of results (one web at a time) | ||||
76 | 17686 | 11.0ms | if ( | ||
77 | ( $this->{partition} eq 'web' ) | ||||
78 | or ( | ||||
79 | scalar( @{ $this->{Itr_list} } ) <= 0 | ||||
80 | ) #no reason to got through the more complex case if there's only one itr | ||||
81 | ) | ||||
82 | { | ||||
83 | 17686 | 2.27ms | my $n; | ||
84 | 17686 | 15.5ms | do { | ||
85 | 17767 | 5.51ms | unless ( $this->{list} ) { | ||
86 | if ( $this->{Itr_index} < scalar( @{ $this->{Itr_list} } ) ) { | ||||
87 | $this->{list} = $this->{Itr_list}->[ $this->{Itr_index}++ ]; | ||||
88 | } | ||||
89 | else { | ||||
90 | 81 | 172µs | return 0; #no more iterators in list | ||
91 | } | ||||
92 | } | ||||
93 | 17686 | 51.7ms | 35291 | 198ms | if ( $this->{list}->hasNext() ) { # spent 124ms making 17605 calls to Foswiki::ListIterator::next, avg 7µs/call
# spent 74.3ms making 17686 calls to Foswiki::ListIterator::hasNext, avg 4µs/call |
94 | $n = $this->{list}->next(); | ||||
95 | } | ||||
96 | else { | ||||
97 | 81 | 42µs | $this->{list} = undef; #goto next iterator | ||
98 | } | ||||
99 | } while ( !$this->{list} ); | ||||
100 | 17605 | 6.96ms | $this->{next} = $n; | ||
101 | } | ||||
102 | else { | ||||
103 | |||||
104 | #yes, this is innefficient, for now I'm looking only to get a functioning result. | ||||
105 | my $next = -1; | ||||
106 | for ( my $idx = 0 ; $idx < scalar( @{ $this->{Itr_list} } ) ; $idx++ ) { | ||||
107 | |||||
108 | #load the next element from each of the iterators | ||||
109 | if ( !defined( $this->{Itr_next}[$idx] ) | ||||
110 | and $this->{Itr_list}[$idx]->hasNext() ) | ||||
111 | { | ||||
112 | $this->{Itr_next}[$idx] = $this->{Itr_list}[$idx]->next(); | ||||
113 | } | ||||
114 | if ( defined( $this->{Itr_next}[$idx] ) ) { | ||||
115 | |||||
116 | #find the first one of them (works because each iterator is already sorted.. | ||||
117 | if ( $next == -1 ) { | ||||
118 | $next = $idx; | ||||
119 | next; | ||||
120 | } | ||||
121 | |||||
122 | #print STDERR "------ trying ($idx) ".$this->{Itr_next}[$idx]."\n"; | ||||
123 | #compare $next's elem with $idx's and rotate if needed | ||||
124 | my @two = ( $this->{Itr_next}[$next], $this->{Itr_next}[$idx] ); | ||||
125 | Foswiki::Search::InfoCache::sortTopics( \@two, $this->{sortby}, | ||||
126 | !$this->{revsort} ); | ||||
127 | if ( $two[0] ne $this->{Itr_next}[$next] ) { | ||||
128 | $next = $idx; | ||||
129 | } | ||||
130 | } | ||||
131 | } | ||||
132 | |||||
133 | #print STDERR "---getting result from $next\n"; | ||||
134 | if ( $next == -1 ) { | ||||
135 | return 0; | ||||
136 | } | ||||
137 | else { | ||||
138 | $this->{next} = $this->{Itr_next}[$next]; | ||||
139 | $this->{Itr_next}[$next] = undef; | ||||
140 | } | ||||
141 | |||||
142 | } | ||||
143 | 17605 | 58.5ms | return 1; | ||
144 | } | ||||
145 | |||||
146 | =begin TML | ||||
147 | |||||
148 | ---++ next() -> $data | ||||
149 | |||||
150 | Return the next entry in the list. | ||||
151 | |||||
152 | =cut | ||||
153 | |||||
154 | # spent 130ms (112+18.5) within Foswiki::Search::ResultSet::next which was called 17605 times, avg 7µs/call:
# 8845 times (43.4ms+8.17ms) by Foswiki::Search::formatResults at line 757 of /var/www/foswiki11/lib/Foswiki/Search.pm, avg 6µs/call
# 8760 times (68.4ms+10.3ms) by Foswiki::Store::QueryAlgorithms::BruteForce::_webQuery at line 210 of /var/www/foswiki11/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm, avg 9µs/call | ||||
155 | 17605 | 4.43ms | my $this = shift; | ||
156 | 17605 | 18.6ms | 17605 | 18.5ms | $this->hasNext(); # spent 18.5ms making 17605 calls to Foswiki::Search::ResultSet::hasNext, avg 1µs/call |
157 | 17605 | 6.47ms | my $n = $this->{next}; | ||
158 | 17605 | 4.17ms | $this->{next} = undef; | ||
159 | |||||
160 | 17605 | 70.1ms | return $n; | ||
161 | } | ||||
162 | |||||
163 | =begin TML | ||||
164 | |||||
165 | ---++ nextWeb() -> $data | ||||
166 | |||||
167 | switch tot he next Web (only works on partition==web, and if we've already started iterating. | ||||
168 | =cut | ||||
169 | |||||
170 | sub nextWeb { | ||||
171 | my $this = shift; | ||||
172 | |||||
173 | ASSERT( $this->{partition} eq 'web' ) if DEBUG; | ||||
174 | ASSERT( $this->{list} ) if DEBUG; | ||||
175 | |||||
176 | $this->{list} = undef; | ||||
177 | $this->hasNext(); | ||||
178 | } | ||||
179 | |||||
180 | =begin TML | ||||
181 | ---++ sortResults | ||||
182 | |||||
183 | the implementation of %SORT{"" limit="" order="" reverse="" date=""}% | ||||
184 | |||||
185 | it should be possible for the search engine to pre-sort, making this a nop, or to | ||||
186 | delay evaluated, partially evaluated, or even delegated to the DB/SQL | ||||
187 | |||||
188 | =cut | ||||
189 | |||||
190 | # spent 54.9ms (1.02+53.9) within Foswiki::Search::ResultSet::sortResults which was called 81 times, avg 678µs/call:
# 41 times (227µs+53.7ms) by Foswiki::Store::QueryAlgorithms::BruteForce::query at line 93 of /var/www/foswiki11/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm, avg 1.32ms/call
# 40 times (788µs+132µs) by Foswiki::Store::SearchAlgorithms::Forking::query at line 198 of /var/www/foswiki11/lib/Foswiki/Store/SearchAlgorithms/Forking.pm, avg 23µs/call | ||||
191 | 81 | 74µs | my ( $this, $params ) = @_; | ||
192 | |||||
193 | 81 | 519µs | foreach my $infocache ( @{ $this->{Itr_list} } ) { | ||
194 | 81 | 225µs | 81 | 53.9ms | $infocache->sortResults($params); # spent 53.9ms making 81 calls to Foswiki::Search::InfoCache::sortResults, avg 665µs/call |
195 | } | ||||
196 | } | ||||
197 | |||||
198 | sub filterByDate { | ||||
199 | my ( $this, $date ) = @_; | ||||
200 | |||||
201 | foreach my $infocache ( @{ $this->{Itr_list} } ) { | ||||
202 | $infocache->filterByDate($date); | ||||
203 | } | ||||
204 | } | ||||
205 | |||||
206 | 1 | 3µs | 1; | ||
207 | __END__ |