| Filename | /usr/lib/x86_64-linux-gnu/perl5/5.28/Template/Iterator.pm |
| Statements | Executed 306916 statements in 774ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 25353 | 4 | 1 | 371ms | 371ms | Template::Iterator::get_next |
| 5248 | 4 | 1 | 102ms | 102ms | Template::Iterator::get_first |
| 5248 | 1 | 1 | 95.6ms | 106ms | Template::Iterator::new |
| 5248 | 4 | 1 | 68.0ms | 89.2ms | Template::Iterator::AUTOLOAD |
| 5248 | 1 | 1 | 21.2ms | 21.2ms | Template::Iterator::CORE:subst (opcode) |
| 1991 | 1 | 1 | 7.49ms | 7.49ms | Template::Iterator::CORE:sort (opcode) |
| 1 | 1 | 1 | 21µs | 28µs | Template::Iterator::BEGIN@24 |
| 1 | 1 | 1 | 15µs | 59µs | Template::Iterator::BEGIN@27 |
| 1 | 1 | 1 | 14µs | 14µs | Template::Iterator::BEGIN@28 |
| 1 | 1 | 1 | 13µs | 55µs | Template::Iterator::BEGIN@25 |
| 1 | 1 | 1 | 12µs | 128µs | Template::Iterator::BEGIN@26 |
| 1 | 1 | 1 | 10µs | 79µs | Template::Iterator::BEGIN@31 |
| 1 | 1 | 1 | 8µs | 44µs | Template::Iterator::BEGIN@29 |
| 1 | 1 | 1 | 6µs | 29µs | Template::Iterator::BEGIN@32 |
| 1 | 1 | 1 | 600ns | 600ns | Template::Iterator::__ANON__ (xsub) |
| 0 | 0 | 0 | 0s | 0s | Template::Iterator::_dump |
| 0 | 0 | 0 | 0s | 0s | Template::Iterator::even |
| 0 | 0 | 0 | 0s | 0s | Template::Iterator::get_all |
| 0 | 0 | 0 | 0s | 0s | Template::Iterator::odd |
| 0 | 0 | 0 | 0s | 0s | Template::Iterator::parity |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | #============================================================= -*-Perl-*- | ||||
| 2 | # | ||||
| 3 | # Template::Iterator | ||||
| 4 | # | ||||
| 5 | # DESCRIPTION | ||||
| 6 | # | ||||
| 7 | # Module defining an iterator class which is used by the FOREACH | ||||
| 8 | # directive for iterating through data sets. This may be | ||||
| 9 | # sub-classed to define more specific iterator types. | ||||
| 10 | # | ||||
| 11 | # AUTHOR | ||||
| 12 | # Andy Wardley <abw@wardley.org> | ||||
| 13 | # | ||||
| 14 | # COPYRIGHT | ||||
| 15 | # Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved. | ||||
| 16 | # | ||||
| 17 | # This module is free software; you can redistribute it and/or | ||||
| 18 | # modify it under the same terms as Perl itself. | ||||
| 19 | # | ||||
| 20 | #============================================================================ | ||||
| 21 | |||||
| 22 | package Template::Iterator; | ||||
| 23 | |||||
| 24 | 2 | 34µs | 2 | 35µs | # spent 28µs (21+7) within Template::Iterator::BEGIN@24 which was called:
# once (21µs+7µs) by Template::Config::load at line 24 # spent 28µs making 1 call to Template::Iterator::BEGIN@24
# spent 7µs making 1 call to strict::import |
| 25 | 2 | 33µs | 2 | 97µs | # spent 55µs (13+42) within Template::Iterator::BEGIN@25 which was called:
# once (13µs+42µs) by Template::Config::load at line 25 # spent 55µs making 1 call to Template::Iterator::BEGIN@25
# spent 42µs making 1 call to warnings::import |
| 26 | 2 | 41µs | 2 | 243µs | # spent 128µs (12+115) within Template::Iterator::BEGIN@26 which was called:
# once (12µs+115µs) by Template::Config::load at line 26 # spent 128µs making 1 call to Template::Iterator::BEGIN@26
# spent 115µs making 1 call to base::import |
| 27 | 2 | 33µs | 2 | 103µs | # spent 59µs (15+44) within Template::Iterator::BEGIN@27 which was called:
# once (15µs+44µs) by Template::Config::load at line 27 # spent 59µs making 1 call to Template::Iterator::BEGIN@27
# spent 44µs making 1 call to Exporter::import |
| 28 | 2 | 33µs | 2 | 15µs | # spent 14µs (14+600ns) within Template::Iterator::BEGIN@28 which was called:
# once (14µs+600ns) by Template::Config::load at line 28 # spent 14µs making 1 call to Template::Iterator::BEGIN@28
# spent 600ns making 1 call to Template::Iterator::__ANON__ |
| 29 | 2 | 29µs | 2 | 79µs | # spent 44µs (8+35) within Template::Iterator::BEGIN@29 which was called:
# once (8µs+35µs) by Template::Config::load at line 29 # spent 44µs making 1 call to Template::Iterator::BEGIN@29
# spent 35µs making 1 call to Exporter::import |
| 30 | |||||
| 31 | 2 | 32µs | 2 | 148µs | # spent 79µs (10+69) within Template::Iterator::BEGIN@31 which was called:
# once (10µs+69µs) by Template::Config::load at line 31 # spent 79µs making 1 call to Template::Iterator::BEGIN@31
# spent 69µs making 1 call to constant::import |
| 32 | 2 | 898µs | 2 | 52µs | # spent 29µs (6+23) within Template::Iterator::BEGIN@32 which was called:
# once (6µs+23µs) by Template::Config::load at line 32 # spent 29µs making 1 call to Template::Iterator::BEGIN@32
# spent 23µs making 1 call to constant::import |
| 33 | |||||
| 34 | 1 | 300ns | our $VERSION = 2.68; | ||
| 35 | 1 | 300ns | our $DEBUG = 0 unless defined $DEBUG; | ||
| 36 | our $AUTOLOAD; | ||||
| 37 | |||||
| 38 | #======================================================================== | ||||
| 39 | # ----- CLASS METHODS ----- | ||||
| 40 | #======================================================================== | ||||
| 41 | |||||
| 42 | #------------------------------------------------------------------------ | ||||
| 43 | # new(\@target, \%options) | ||||
| 44 | # | ||||
| 45 | # Constructor method which creates and returns a reference to a new | ||||
| 46 | # Template::Iterator object. A reference to the target data (array | ||||
| 47 | # or hash) may be passed for the object to iterate through. | ||||
| 48 | #------------------------------------------------------------------------ | ||||
| 49 | |||||
| 50 | # spent 106ms (95.6+10.6) within Template::Iterator::new which was called 5248 times, avg 20µs/call:
# 5248 times (95.6ms+10.6ms) by Template::Config::iterator at line 177 of Template/Config.pm, avg 20µs/call | ||||
| 51 | 5248 | 4.51ms | my $class = shift; | ||
| 52 | 5248 | 4.44ms | my $data = shift || [ ]; | ||
| 53 | 5248 | 3.76ms | my $params = shift || { }; | ||
| 54 | |||||
| 55 | 5248 | 60.4ms | 5248 | 10.6ms | if (ref $data eq 'HASH') { # spent 7.49ms making 1991 calls to Template::Iterator::CORE:sort, avg 4µs/call
# spent 3.11ms making 3257 calls to Scalar::Util::blessed, avg 954ns/call |
| 56 | # map a hash into a list of { key => ???, value => ??? } hashes, | ||||
| 57 | # one for each key, sorted by keys | ||||
| 58 | $data = [ map { { key => $_, value => $data->{ $_ } } } | ||||
| 59 | sort keys %$data ]; | ||||
| 60 | } | ||||
| 61 | elsif (blessed($data) && $data->can('as_list')) { | ||||
| 62 | $data = $data->as_list(); | ||||
| 63 | } | ||||
| 64 | elsif (ref $data ne 'ARRAY') { | ||||
| 65 | # coerce any non-list data into an array reference | ||||
| 66 | $data = [ $data ] ; | ||||
| 67 | } | ||||
| 68 | |||||
| 69 | bless { | ||||
| 70 | 5248 | 41.3ms | _DATA => $data, | ||
| 71 | _ERROR => '', | ||||
| 72 | }, $class; | ||||
| 73 | } | ||||
| 74 | |||||
| 75 | |||||
| 76 | #======================================================================== | ||||
| 77 | # ----- PUBLIC OBJECT METHODS ----- | ||||
| 78 | #======================================================================== | ||||
| 79 | |||||
| 80 | #------------------------------------------------------------------------ | ||||
| 81 | # get_first() | ||||
| 82 | # | ||||
| 83 | # Initialises the object for iterating through the target data set. The | ||||
| 84 | # first record is returned, if defined, along with the STATUS_OK value. | ||||
| 85 | # If there is no target data, or the data is an empty set, then undef | ||||
| 86 | # is returned with the STATUS_DONE value. | ||||
| 87 | #------------------------------------------------------------------------ | ||||
| 88 | |||||
| 89 | # spent 102ms within Template::Iterator::get_first which was called 5248 times, avg 20µs/call:
# 1991 times (40.7ms+0s) by Template::Document::__ANON__[input text:22] at line 15 of /root/tor-browser-build/input text, avg 20µs/call
# 1991 times (39.0ms+0s) by Template::Document::__ANON__[input text:43] at line 22 of /root/tor-browser-build/input text, avg 20µs/call
# 993 times (17.3ms+0s) by Template::Document::__ANON__[input text:35] at line 20 of /root/tor-browser-build/input text, avg 17µs/call
# 273 times (5.36ms+0s) by Template::Document::__ANON__[input text:35] at line 32 of /root/tor-browser-build/input text, avg 20µs/call | ||||
| 90 | 5248 | 2.85ms | my $self = shift; | ||
| 91 | 5248 | 6.20ms | my $data = $self->{ _DATA }; | ||
| 92 | |||||
| 93 | 5248 | 12.0ms | $self->{ _DATASET } = $self->{ _DATA }; | ||
| 94 | 5248 | 3.43ms | my $size = scalar @$data; | ||
| 95 | 5248 | 2.02ms | my $index = 0; | ||
| 96 | |||||
| 97 | 5248 | 5.04ms | return (undef, Template::Constants::STATUS_DONE) unless $size; | ||
| 98 | |||||
| 99 | # initialise various counters, flags, etc. | ||||
| 100 | 4777 | 38.7ms | @$self{ qw( SIZE MAX INDEX COUNT FIRST LAST ) } | ||
| 101 | = ( $size, $size - 1, $index, 1, 1, $size > 1 ? 0 : 1, undef ); | ||||
| 102 | 4777 | 21.4ms | @$self{ qw( PREV NEXT ) } = ( undef, $self->{ _DATASET }->[ $index + 1 ]); | ||
| 103 | |||||
| 104 | 4777 | 26.6ms | return $self->{ _DATASET }->[ $index ]; | ||
| 105 | } | ||||
| 106 | |||||
| - - | |||||
| 109 | #------------------------------------------------------------------------ | ||||
| 110 | # get_next() | ||||
| 111 | # | ||||
| 112 | # Called repeatedly to access successive elements in the data set. | ||||
| 113 | # Should only be called after calling get_first() or a warning will | ||||
| 114 | # be raised and (undef, STATUS_DONE) returned. | ||||
| 115 | #------------------------------------------------------------------------ | ||||
| 116 | |||||
| 117 | # spent 371ms within Template::Iterator::get_next which was called 25353 times, avg 15µs/call:
# 19910 times (324ms+0s) by Template::Document::__ANON__[input text:43] at line 14 of /root/tor-browser-build/input text, avg 16µs/call
# 3982 times (29.2ms+0s) by Template::Document::__ANON__[input text:22] at line 5 of /root/tor-browser-build/input text, avg 7µs/call
# 981 times (13.9ms+0s) by Template::Document::__ANON__[input text:35] at line 10 of /root/tor-browser-build/input text, avg 14µs/call
# 480 times (3.08ms+0s) by Template::Document::__ANON__[input text:35] at line 22 of /root/tor-browser-build/input text, avg 6µs/call | ||||
| 118 | 25353 | 17.3ms | my $self = shift; | ||
| 119 | 25353 | 53.4ms | my ($max, $index) = @$self{ qw( MAX INDEX ) }; | ||
| 120 | 25353 | 31.5ms | my $data = $self->{ _DATASET }; | ||
| 121 | |||||
| 122 | # warn about incorrect usage | ||||
| 123 | 25353 | 18.8ms | unless (defined $index) { | ||
| 124 | my ($pack, $file, $line) = caller(); | ||||
| 125 | warn("iterator get_next() called before get_first() at $file line $line\n"); | ||||
| 126 | return (undef, Template::Constants::STATUS_DONE); ## RETURN ## | ||||
| 127 | } | ||||
| 128 | |||||
| 129 | # if there's still some data to go... | ||||
| 130 | 25353 | 15.0ms | if ($index < $max) { | ||
| 131 | # update counters and flags | ||||
| 132 | 20576 | 6.65ms | $index++; | ||
| 133 | 20576 | 62.8ms | @$self{ qw( INDEX COUNT FIRST LAST ) } | ||
| 134 | = ( $index, $index + 1, 0, $index == $max ? 1 : 0 ); | ||||
| 135 | 20576 | 77.4ms | @$self{ qw( PREV NEXT ) } = @$data[ $index - 1, $index + 1 ]; | ||
| 136 | 20576 | 106ms | return $data->[ $index ]; ## RETURN ## | ||
| 137 | } | ||||
| 138 | else { | ||||
| 139 | 4777 | 44.2ms | return (undef, Template::Constants::STATUS_DONE); ## RETURN ## | ||
| 140 | } | ||||
| 141 | } | ||||
| 142 | |||||
| 143 | |||||
| 144 | #------------------------------------------------------------------------ | ||||
| 145 | # get_all() | ||||
| 146 | # | ||||
| 147 | # Method which returns all remaining items in the iterator as a Perl list | ||||
| 148 | # reference. May be called at any time in the life-cycle of the iterator. | ||||
| 149 | # The get_first() method will be called automatically if necessary, and | ||||
| 150 | # then subsequent get_next() calls are made, storing each returned | ||||
| 151 | # result until the list is exhausted. | ||||
| 152 | #------------------------------------------------------------------------ | ||||
| 153 | |||||
| 154 | sub get_all { | ||||
| 155 | my $self = shift; | ||||
| 156 | my ($max, $index) = @$self{ qw( MAX INDEX ) }; | ||||
| 157 | my @data; | ||||
| 158 | |||||
| 159 | # handle cases where get_first() has yet to be called. | ||||
| 160 | unless (defined $index) { | ||||
| 161 | my ($first, $status) = $self->get_first; | ||||
| 162 | |||||
| 163 | # refresh $max and $index, after get_first updates MAX and INDEX | ||||
| 164 | ($max, $index) = @$self{ qw( MAX INDEX ) }; | ||||
| 165 | |||||
| 166 | # empty lists are handled here. | ||||
| 167 | if ($status && $status == Template::Constants::STATUS_DONE) { | ||||
| 168 | return (undef, Template::Constants::STATUS_DONE); ## RETURN ## | ||||
| 169 | } | ||||
| 170 | |||||
| 171 | push @data, $first; | ||||
| 172 | |||||
| 173 | ## if there's nothing left in the iterator, return the single value. | ||||
| 174 | unless ($index < $max) { | ||||
| 175 | return \@data; | ||||
| 176 | } | ||||
| 177 | } | ||||
| 178 | |||||
| 179 | # if there's still some data to go... | ||||
| 180 | if ($index < $max) { | ||||
| 181 | $index++; | ||||
| 182 | push @data, @{ $self->{ _DATASET } } [ $index..$max ]; | ||||
| 183 | |||||
| 184 | # update counters and flags | ||||
| 185 | @$self{ qw( INDEX COUNT FIRST LAST ) } | ||||
| 186 | = ( $max, $max + 1, 0, 1 ); | ||||
| 187 | |||||
| 188 | return \@data; ## RETURN ## | ||||
| 189 | } | ||||
| 190 | else { | ||||
| 191 | return (undef, Template::Constants::STATUS_DONE); ## RETURN ## | ||||
| 192 | } | ||||
| 193 | } | ||||
| 194 | |||||
| 195 | sub odd { | ||||
| 196 | shift->{ COUNT } % 2 ? 1 : 0 | ||||
| 197 | } | ||||
| 198 | |||||
| 199 | sub even { | ||||
| 200 | shift->{ COUNT } % 2 ? 0 : 1 | ||||
| 201 | } | ||||
| 202 | |||||
| 203 | sub parity { | ||||
| 204 | shift->{ COUNT } % 2 ? ODD : EVEN; | ||||
| 205 | } | ||||
| 206 | |||||
| 207 | |||||
| 208 | #------------------------------------------------------------------------ | ||||
| 209 | # AUTOLOAD | ||||
| 210 | # | ||||
| 211 | # Provides access to internal fields (e.g. size, first, last, max, etc) | ||||
| 212 | #------------------------------------------------------------------------ | ||||
| 213 | |||||
| 214 | # spent 89.2ms (68.0+21.2) within Template::Iterator::AUTOLOAD which was called 5248 times, avg 17µs/call:
# 1991 times (31.7ms+5.72ms) by Template::Document::__ANON__[input text:43] at line 20 of /root/tor-browser-build/input text, avg 19µs/call
# 1991 times (23.7ms+10.9ms) by Template::Document::__ANON__[input text:22] at line 11 of /root/tor-browser-build/input text, avg 17µs/call
# 993 times (9.86ms+3.33ms) by Template::Document::__ANON__[input text:35] at line 16 of /root/tor-browser-build/input text, avg 13µs/call
# 273 times (2.72ms+1.28ms) by Template::Document::__ANON__[input text:35] at line 28 of /root/tor-browser-build/input text, avg 15µs/call | ||||
| 215 | 5248 | 3.81ms | my $self = shift; | ||
| 216 | 5248 | 5.66ms | my $item = $AUTOLOAD; | ||
| 217 | 5248 | 68.0ms | 5248 | 21.2ms | $item =~ s/.*:://; # spent 21.2ms making 5248 calls to Template::Iterator::CORE:subst, avg 4µs/call |
| 218 | 5248 | 30.2ms | return if $item eq 'DESTROY'; | ||
| 219 | |||||
| 220 | # alias NUMBER to COUNT for backwards compatibility | ||||
| 221 | $item = 'COUNT' if $item =~ /NUMBER/i; | ||||
| 222 | |||||
| 223 | return $self->{ uc $item }; | ||||
| 224 | } | ||||
| 225 | |||||
| 226 | |||||
| 227 | #======================================================================== | ||||
| 228 | # ----- PRIVATE DEBUG METHODS ----- | ||||
| 229 | #======================================================================== | ||||
| 230 | |||||
| 231 | #------------------------------------------------------------------------ | ||||
| 232 | # _dump() | ||||
| 233 | # | ||||
| 234 | # Debug method which returns a string detailing the internal state of | ||||
| 235 | # the iterator object. | ||||
| 236 | #------------------------------------------------------------------------ | ||||
| 237 | |||||
| 238 | sub _dump { | ||||
| 239 | my $self = shift; | ||||
| 240 | join('', | ||||
| 241 | " Data: ", $self->{ _DATA }, "\n", | ||||
| 242 | " Index: ", $self->{ INDEX }, "\n", | ||||
| 243 | "Number: ", $self->{ NUMBER }, "\n", | ||||
| 244 | " Max: ", $self->{ MAX }, "\n", | ||||
| 245 | " Size: ", $self->{ SIZE }, "\n", | ||||
| 246 | " First: ", $self->{ FIRST }, "\n", | ||||
| 247 | " Last: ", $self->{ LAST }, "\n", | ||||
| 248 | "\n" | ||||
| 249 | ); | ||||
| 250 | } | ||||
| 251 | |||||
| 252 | |||||
| 253 | 1 | 4µs | 1; | ||
| 254 | |||||
| 255 | __END__ | ||||
# spent 7.49ms within Template::Iterator::CORE:sort which was called 1991 times, avg 4µs/call:
# 1991 times (7.49ms+0s) by Template::Iterator::new at line 55, avg 4µs/call | |||||
# spent 21.2ms within Template::Iterator::CORE:subst which was called 5248 times, avg 4µs/call:
# 5248 times (21.2ms+0s) by Template::Iterator::AUTOLOAD at line 217, avg 4µs/call | |||||
# spent 600ns within Template::Iterator::__ANON__ which was called:
# once (600ns+0s) by Template::Iterator::BEGIN@28 at line 28 |