Filename | /usr/local/src/github.com/foswiki/core/lib/Foswiki/Iterator/PagerIterator.pm |
Statements | Executed 10 statements in 1.28ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 24µs | 32µs | BEGIN@13 | Foswiki::Iterator::PagerIterator::
1 | 1 | 1 | 21µs | 59µs | BEGIN@15 | Foswiki::Iterator::PagerIterator::
1 | 1 | 1 | 17µs | 35µs | BEGIN@14 | Foswiki::Iterator::PagerIterator::
1 | 1 | 1 | 9µs | 9µs | BEGIN@17 | Foswiki::Iterator::PagerIterator::
0 | 0 | 0 | 0s | 0s | hasNext | Foswiki::Iterator::PagerIterator::
0 | 0 | 0 | 0s | 0s | new | Foswiki::Iterator::PagerIterator::
0 | 0 | 0 | 0s | 0s | next | Foswiki::Iterator::PagerIterator::
0 | 0 | 0 | 0s | 0s | nextWeb | Foswiki::Iterator::PagerIterator::
0 | 0 | 0 | 0s | 0s | numberOfPages | Foswiki::Iterator::PagerIterator::
0 | 0 | 0 | 0s | 0s | numberOfTopics | Foswiki::Iterator::PagerIterator::
0 | 0 | 0 | 0s | 0s | pagesize | Foswiki::Iterator::PagerIterator::
0 | 0 | 0 | 0s | 0s | reset | Foswiki::Iterator::PagerIterator::
0 | 0 | 0 | 0s | 0s | showpage | Foswiki::Iterator::PagerIterator::
0 | 0 | 0 | 0s | 0s | skip | Foswiki::Iterator::PagerIterator::
0 | 0 | 0 | 0s | 0s | sortResults | Foswiki::Iterator::PagerIterator::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # See bottom of file for license and copyright information | ||||
2 | |||||
3 | =begin | ||||
4 | |||||
5 | ---+ package Foswiki::Iterator::PagerIterator | ||||
6 | |||||
7 | Iterator that Pages another iterator | ||||
8 | |||||
9 | =cut | ||||
10 | |||||
11 | package Foswiki::Iterator::PagerIterator; | ||||
12 | |||||
13 | 2 | 47µs | 2 | 40µs | # spent 32µs (24+8) within Foswiki::Iterator::PagerIterator::BEGIN@13 which was called:
# once (24µs+8µs) by Foswiki::Search::BEGIN@23 at line 13 # spent 32µs making 1 call to Foswiki::Iterator::PagerIterator::BEGIN@13
# spent 7µs making 1 call to strict::import |
14 | 2 | 43µs | 2 | 53µs | # spent 35µs (17+18) within Foswiki::Iterator::PagerIterator::BEGIN@14 which was called:
# once (17µs+18µs) by Foswiki::Search::BEGIN@23 at line 14 # spent 35µs making 1 call to Foswiki::Iterator::PagerIterator::BEGIN@14
# spent 18µs making 1 call to warnings::import |
15 | 2 | 44µs | 2 | 97µs | # spent 59µs (21+38) within Foswiki::Iterator::PagerIterator::BEGIN@15 which was called:
# once (21µs+38µs) by Foswiki::Search::BEGIN@23 at line 15 # spent 59µs making 1 call to Foswiki::Iterator::PagerIterator::BEGIN@15
# spent 38µs making 1 call to Assert::import |
16 | |||||
17 | 2 | 1.13ms | 1 | 9µs | # spent 9µs within Foswiki::Iterator::PagerIterator::BEGIN@17 which was called:
# once (9µs+0s) by Foswiki::Search::BEGIN@23 at line 17 # spent 9µs making 1 call to Foswiki::Iterator::PagerIterator::BEGIN@17 |
18 | 1 | 9µs | our @ISA = ('Foswiki::Iterator'); | ||
19 | |||||
20 | =begin TML | ||||
21 | |||||
22 | ---++ ClassMethod new( $iter, $pagesize, $showpage) | ||||
23 | |||||
24 | skip a certain number of results based on pagesize and page number | ||||
25 | |||||
26 | (page 1 is the first page) | ||||
27 | |||||
28 | =cut | ||||
29 | |||||
30 | sub new { | ||||
31 | my ( $class, $iter, $pagesize, $showpage ) = @_; | ||||
32 | ASSERT( UNIVERSAL::isa( $iter, 'Foswiki::Iterator' ) ) if DEBUG; | ||||
33 | |||||
34 | my $this = bless( {}, $class ); | ||||
35 | $this->{iterator} = $iter; | ||||
36 | |||||
37 | $this->{next} = undef; | ||||
38 | $this->{pending} = | ||||
39 | 0; #has 'hasNext' already been called, but 'next' hasn't been | ||||
40 | |||||
41 | $this->{pagesize} = | ||||
42 | $pagesize | ||||
43 | || $Foswiki::cfg{Search}{DefaultPageSize} | ||||
44 | || 25; | ||||
45 | $this->{showpage} = $showpage; | ||||
46 | $this->{showpage} = 1 unless ( defined( $this->{showpage} ) ); | ||||
47 | |||||
48 | $this->{pager_skip_results_from} = | ||||
49 | $this->{pagesize} * ( $this->{showpage} - 1 ); | ||||
50 | print STDERR | ||||
51 | " $this->{pager_skip_results_from} = $this->{pagesize} * ($this->{showpage}-1);\n" | ||||
52 | if Foswiki::Iterator::MONITOR; | ||||
53 | $this->{pager_result_count} = $this->{pagesize}; | ||||
54 | |||||
55 | return $this; | ||||
56 | } | ||||
57 | |||||
58 | sub pagesize { | ||||
59 | my $this = shift; | ||||
60 | return $this->{pagesize}; | ||||
61 | } | ||||
62 | |||||
63 | sub showpage { | ||||
64 | my $this = shift; | ||||
65 | return $this->{showpage}; | ||||
66 | } | ||||
67 | |||||
68 | #lie - give the requested pagesize - it might be less, if we're at the end of the list | ||||
69 | sub numberOfTopics { | ||||
70 | my $this = shift; | ||||
71 | return $this->{pagesize}; | ||||
72 | } | ||||
73 | |||||
74 | #another lie - this hopes that the inner iterator knows the number, and isn't just guessing. | ||||
75 | sub numberOfPages { | ||||
76 | my $this = shift; | ||||
77 | return int( $this->{iterator}->numberOfTopics() / $this->{pagesize} ) + 1; | ||||
78 | } | ||||
79 | |||||
80 | sub nextWeb { | ||||
81 | my $this = shift; | ||||
82 | $this->{iterator}->nextWeb(); | ||||
83 | } | ||||
84 | |||||
85 | sub sortResults { | ||||
86 | my $this = shift; | ||||
87 | $this->{iterator}->sortResults(@_); | ||||
88 | } | ||||
89 | |||||
90 | # See Foswiki::Iterator for a description of the general iterator contract | ||||
91 | sub hasNext { | ||||
92 | my $this = shift; | ||||
93 | return 1 if $this->{pending}; | ||||
94 | |||||
95 | if ( $this->{pager_skip_results_from} > 0 ) { | ||||
96 | $this->{pager_skip_results_from} = | ||||
97 | $this->skip( $this->{pager_skip_results_from} ); | ||||
98 | |||||
99 | #this already loads $this->{next} | ||||
100 | } | ||||
101 | else { | ||||
102 | if ( $this->{iterator}->hasNext() ) { | ||||
103 | $this->{next} = $this->{iterator}->next(); | ||||
104 | $this->{pending} = 1; | ||||
105 | } | ||||
106 | } | ||||
107 | |||||
108 | if ( $this->{pending} ) { | ||||
109 | if ( $this->{pager_result_count} <= 0 ) { | ||||
110 | |||||
111 | #finished. | ||||
112 | $this->{next} = undef; | ||||
113 | $this->{pending} = 0; | ||||
114 | return 0; | ||||
115 | } | ||||
116 | $this->{pager_result_count}--; | ||||
117 | return 1; | ||||
118 | } | ||||
119 | return 0; | ||||
120 | } | ||||
121 | |||||
122 | #skip X elements (returns 0 if successful, or number of elements remaining to skip if there are not enough elements to skip) | ||||
123 | #skip must set up next as though hasNext was called. | ||||
124 | sub skip { | ||||
125 | my $this = shift; | ||||
126 | my $count = shift; | ||||
127 | |||||
128 | print STDERR | ||||
129 | "--------------------------------------------PagerIterator::skip($count)\n" | ||||
130 | if Foswiki::Iterator::MONITOR; | ||||
131 | |||||
132 | #ask CAN skip() for faster path | ||||
133 | if ( $this->{iterator}->can('skip') ) { | ||||
134 | $count = $this->{iterator}->skip($count); | ||||
135 | $this->{next} = $this->{iterator}->{next}; | ||||
136 | $this->{pending} = defined( $this->{next} ); | ||||
137 | } | ||||
138 | else { | ||||
139 | |||||
140 | #brute force | ||||
141 | while ( | ||||
142 | ( $count >= 0 | ||||
143 | ) #must come first - don't want to advance the inner itr if count ==0 | ||||
144 | and $this->{iterator}->hasNext() | ||||
145 | ) | ||||
146 | { | ||||
147 | $count--; | ||||
148 | $this->{next} = | ||||
149 | $this->{iterator}->next() | ||||
150 | ; #drain next, so hasNext goes to next element | ||||
151 | $this->{pending} = defined( $this->{next} ); | ||||
152 | } | ||||
153 | } | ||||
154 | |||||
155 | if ( $count >= 0 ) { | ||||
156 | |||||
157 | #finished. | ||||
158 | $this->{next} = undef; | ||||
159 | $this->{pending} = 0; | ||||
160 | } | ||||
161 | print STDERR | ||||
162 | "--------------------------------------------PagerIterator::skip() => $count\n" | ||||
163 | if Foswiki::Iterator::MONITOR; | ||||
164 | |||||
165 | return $count; | ||||
166 | } | ||||
167 | |||||
168 | # See Foswiki::Iterator for a description of the general iterator contract | ||||
169 | sub next { | ||||
170 | my $this = shift; | ||||
171 | return unless $this->hasNext(); | ||||
172 | $this->{pending} = 0; | ||||
173 | return $this->{next}; | ||||
174 | } | ||||
175 | |||||
176 | # See Foswiki::Iterator for a description of the general iterator contract | ||||
177 | sub reset { | ||||
178 | my ($this) = @_; | ||||
179 | |||||
180 | return unless ( $this->{iterator}->reset() ); | ||||
181 | $this->{next} = undef; | ||||
182 | $this->{pending} = 0; | ||||
183 | |||||
184 | return 1; | ||||
185 | } | ||||
186 | |||||
187 | 1 | 6µs | 1; | ||
188 | __END__ |