Filename | /var/www/foswiki11/lib/Foswiki/AggregateIterator.pm |
Statements | Executed 8 statements in 428µs |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 270µs | 375µs | BEGIN@16 | Foswiki::AggregateIterator::
1 | 1 | 1 | 15µs | 28µs | BEGIN@13 | Foswiki::AggregateIterator::
1 | 1 | 1 | 8µs | 13µs | BEGIN@14 | Foswiki::AggregateIterator::
0 | 0 | 0 | 0s | 0s | hasNext | Foswiki::AggregateIterator::
0 | 0 | 0 | 0s | 0s | new | Foswiki::AggregateIterator::
0 | 0 | 0 | 0s | 0s | next | Foswiki::AggregateIterator::
0 | 0 | 0 | 0s | 0s | unique | Foswiki::AggregateIterator::
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::AggregateIterator | ||||
6 | *implements* Foswiki::Iterator | ||||
7 | |||||
8 | Combine multiple iterators into a single iteration. | ||||
9 | |||||
10 | =cut | ||||
11 | |||||
12 | package Foswiki::AggregateIterator; | ||||
13 | 2 | 26µs | 2 | 40µs | # spent 28µs (15+12) within Foswiki::AggregateIterator::BEGIN@13 which was called:
# once (15µs+12µs) by Foswiki::Users::BEGIN@63 at line 13 # spent 28µs making 1 call to Foswiki::AggregateIterator::BEGIN@13
# spent 12µs making 1 call to strict::import |
14 | 2 | 22µs | 2 | 18µs | # spent 13µs (8+5) within Foswiki::AggregateIterator::BEGIN@14 which was called:
# once (8µs+5µs) by Foswiki::Users::BEGIN@63 at line 14 # spent 13µs making 1 call to Foswiki::AggregateIterator::BEGIN@14
# spent 5µs making 1 call to warnings::import |
15 | |||||
16 | 2 | 370µs | 1 | 375µs | # spent 375µs (270+105) within Foswiki::AggregateIterator::BEGIN@16 which was called:
# once (270µs+105µs) by Foswiki::Users::BEGIN@63 at line 16 # spent 375µs making 1 call to Foswiki::AggregateIterator::BEGIN@16 |
17 | 1 | 8µs | our @ISA = ('Foswiki::Iterator'); | ||
18 | |||||
19 | =begin TML | ||||
20 | |||||
21 | ---++ new(\@list, $unique) | ||||
22 | |||||
23 | Create a new iterator over the given list of iterators. The list is | ||||
24 | not damaged in any way. | ||||
25 | |||||
26 | If =$unique= is set, we try to not repeat values. | ||||
27 | Warning: =$unique= assumes that the values are strings. | ||||
28 | |||||
29 | =cut | ||||
30 | |||||
31 | sub new { | ||||
32 | my ( $class, $list, $unique ) = @_; | ||||
33 | my $this = bless( | ||||
34 | { | ||||
35 | Itr_list => $list, | ||||
36 | Itr_index => 0, | ||||
37 | index => 0, | ||||
38 | process => undef, | ||||
39 | filter => undef, | ||||
40 | next => undef, | ||||
41 | unique => $unique, | ||||
42 | unique_hash => {} | ||||
43 | }, | ||||
44 | $class | ||||
45 | ); | ||||
46 | return $this; | ||||
47 | } | ||||
48 | |||||
49 | =begin TML | ||||
50 | |||||
51 | ---++ hasNext() -> $boolean | ||||
52 | |||||
53 | Returns false when the iterator is exhausted. | ||||
54 | |||||
55 | =cut | ||||
56 | |||||
57 | sub hasNext { | ||||
58 | my ($this) = @_; | ||||
59 | return 1 if $this->{next}; | ||||
60 | my $n; | ||||
61 | do { | ||||
62 | unless ( $this->{list} ) { | ||||
63 | if ( $this->{Itr_index} < scalar( @{ $this->{Itr_list} } ) ) { | ||||
64 | $this->{list} = $this->{Itr_list}->[ $this->{Itr_index}++ ]; | ||||
65 | } | ||||
66 | else { | ||||
67 | return 0; #no more iterators in list | ||||
68 | } | ||||
69 | } | ||||
70 | if ( $this->{list}->hasNext() ) { | ||||
71 | $n = $this->{list}->next(); | ||||
72 | } | ||||
73 | else { | ||||
74 | $this->{list} = undef; #goto next iterator | ||||
75 | } | ||||
76 | } while ( !$this->{list} | ||||
77 | || ( $this->{filter} && !&{ $this->{filter} }($n) ) | ||||
78 | || ( $this->{unique} && !$this->unique($n) ) ); | ||||
79 | $this->{next} = $n; | ||||
80 | return 1; | ||||
81 | } | ||||
82 | |||||
83 | sub unique { | ||||
84 | my ( $this, $value ) = @_; | ||||
85 | |||||
86 | unless ( defined( $this->{unique_hash}{$value} ) ) { | ||||
87 | $this->{unique_hash}{$value} = 1; | ||||
88 | return 1; | ||||
89 | } | ||||
90 | |||||
91 | return 0; | ||||
92 | } | ||||
93 | |||||
94 | =begin TML | ||||
95 | |||||
96 | ---++ next() -> $data | ||||
97 | |||||
98 | Return the next entry in the list. | ||||
99 | |||||
100 | The iterator object can be customised to pre- and post-process entries from | ||||
101 | the list before returning them. This is done by setting two fields in the | ||||
102 | iterator object: | ||||
103 | |||||
104 | * ={filter}= can be defined to be a sub that filters each entry. The entry | ||||
105 | will be ignored (next() will not return it) if the filter returns false. | ||||
106 | * ={process}= can be defined to be a sub to process each entry before it | ||||
107 | is returned by next. The value returned from next is the value returned | ||||
108 | by the process function. | ||||
109 | |||||
110 | =cut | ||||
111 | |||||
112 | sub next { | ||||
113 | my $this = shift; | ||||
114 | $this->hasNext(); | ||||
115 | my $n = $this->{next}; | ||||
116 | $this->{next} = undef; | ||||
117 | $n = &{ $this->{process} }($n) if $this->{process}; | ||||
118 | |||||
119 | #print STDERR "next - $n \n"; | ||||
120 | return $n; | ||||
121 | } | ||||
122 | |||||
123 | 1 | 3µs | 1; | ||
124 | __END__ |