Filename | /var/www/foswiki11/lib/Foswiki/Prefs/Stack.pm |
Statements | Executed 28142 statements in 52.2ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
861 | 1 | 1 | 16.0ms | 21.2ms | getPreference | Foswiki::Prefs::Stack::
130 | 8 | 1 | 10.2ms | 11.4ms | newLevel | Foswiki::Prefs::Stack::
42 | 2 | 2 | 5.66ms | 5.66ms | restore | Foswiki::Prefs::Stack::
941 | 2 | 1 | 3.45ms | 3.45ms | _getLevel | Foswiki::Prefs::Stack::
570 | 1 | 1 | 2.20ms | 2.20ms | finalizedBefore | Foswiki::Prefs::Stack::
659 | 3 | 1 | 1.36ms | 1.36ms | backAtLevel | Foswiki::Prefs::Stack::
36 | 1 | 1 | 1.23ms | 3.91ms | clone | Foswiki::Prefs::Stack::
570 | 1 | 1 | 1.22ms | 1.22ms | prefIsDefined | Foswiki::Prefs::Stack::
128 | 3 | 2 | 1.01ms | 1.01ms | new | Foswiki::Prefs::Stack::
93 | 2 | 2 | 865µs | 1.15ms | finish | Foswiki::Prefs::Stack::
83 | 1 | 1 | 507µs | 944µs | getDefinitionLevel | Foswiki::Prefs::Stack::
48 | 2 | 1 | 463µs | 1.00ms | insert | Foswiki::Prefs::Stack::
156 | 4 | 2 | 382µs | 382µs | size | Foswiki::Prefs::Stack::
1 | 1 | 1 | 206µs | 209µs | BEGIN@28 | Foswiki::Prefs::Stack::
8 | 1 | 1 | 52µs | 52µs | finalized | Foswiki::Prefs::Stack::
1 | 1 | 1 | 16µs | 30µs | BEGIN@26 | Foswiki::Prefs::Stack::
1 | 1 | 1 | 9µs | 15µs | BEGIN@27 | Foswiki::Prefs::Stack::
0 | 0 | 0 | 0s | 0s | prefs | Foswiki::Prefs::Stack::
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 | ---+ UNPUBLISHED package Foswiki::Prefs::Stack | ||||
6 | |||||
7 | Foswiki preferences mechanism are like stacks: | ||||
8 | * Preferences pushed later have precedence over ones pushed earlier I must | ||||
9 | * be able to return (restore) to a state I was earlier | ||||
10 | |||||
11 | This stack can exist as an index, so preference data is not copied everywhere. | ||||
12 | |||||
13 | The index is composed by three elements: | ||||
14 | * A bitstring map. Each preference has a bitmap. Each bit corresponds to a | ||||
15 | level. The bit is 1 if the preference is defined at that level and 0 | ||||
16 | otherwise. If a preference is "defined" in some level, but it was | ||||
17 | finalized, then the corresponding bit is 0. | ||||
18 | * A level list storing a backend object that is associated with each level | ||||
19 | * A final hash that maps preferences to the level they were finalized. | ||||
20 | |||||
21 | This class deals with this stuff and must be used only by =Foswiki::Prefs= | ||||
22 | |||||
23 | =cut | ||||
24 | |||||
25 | package Foswiki::Prefs::Stack; | ||||
26 | 2 | 27µs | 2 | 44µs | # spent 30µs (16+14) within Foswiki::Prefs::Stack::BEGIN@26 which was called:
# once (16µs+14µs) by Foswiki::Prefs::BEGIN@70 at line 26 # spent 30µs making 1 call to Foswiki::Prefs::Stack::BEGIN@26
# spent 14µs making 1 call to strict::import |
27 | 2 | 26µs | 2 | 21µs | # spent 15µs (9+6) within Foswiki::Prefs::Stack::BEGIN@27 which was called:
# once (9µs+6µs) by Foswiki::Prefs::BEGIN@70 at line 27 # spent 15µs making 1 call to Foswiki::Prefs::Stack::BEGIN@27
# spent 6µs making 1 call to warnings::import |
28 | 2 | 1.14ms | 2 | 212µs | # spent 209µs (206+3) within Foswiki::Prefs::Stack::BEGIN@28 which was called:
# once (206µs+3µs) by Foswiki::Prefs::BEGIN@70 at line 28 # spent 209µs making 1 call to Foswiki::Prefs::Stack::BEGIN@28
# spent 3µs making 1 call to bytes::import |
29 | |||||
30 | =begin TML | ||||
31 | |||||
32 | ---++ ClassMethod new( $session ) | ||||
33 | |||||
34 | Creates a new Stack object. | ||||
35 | |||||
36 | =cut | ||||
37 | |||||
38 | # spent 1.01ms within Foswiki::Prefs::Stack::new which was called 128 times, avg 8µs/call:
# 91 times (768µs+0s) by Foswiki::Prefs::_getWebPrefsObj at line 183 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 8µs/call
# 36 times (229µs+0s) by Foswiki::Prefs::Stack::clone at line 270, avg 6µs/call
# once (10µs+0s) by Foswiki::Prefs::new at line 85 of /var/www/foswiki11/lib/Foswiki/Prefs.pm | ||||
39 | 128 | 83µs | my $proto = shift; | ||
40 | 128 | 112µs | my $class = ref($proto) || $proto; | ||
41 | 128 | 420µs | my $this = { | ||
42 | 'final' => {}, # Map preferences to the level the were finalized. | ||||
43 | 'levels' => [], # Maps leves to the corresponding backend objects. | ||||
44 | 'map' => {}, # Associate each preference with its bitstring map. | ||||
45 | }; | ||||
46 | 128 | 591µs | return bless $this, $class; | ||
47 | } | ||||
48 | |||||
49 | =begin TML | ||||
50 | |||||
51 | ---++ ObjectMethod finish() | ||||
52 | |||||
53 | Break circular references. | ||||
54 | |||||
55 | =cut | ||||
56 | |||||
57 | # Note to developers; please undef *all* fields in the object explicitly, | ||||
58 | # whether they are references or not. That way this method is "golden | ||||
59 | # documentation" of the live fields in the object. | ||||
60 | # spent 1.15ms (865µs+281µs) within Foswiki::Prefs::Stack::finish which was called 93 times, avg 12µs/call:
# 92 times (643µs+187µs) by Foswiki::Prefs::Web::finish at line 53 of /var/www/foswiki11/lib/Foswiki/Prefs/Web.pm, avg 9µs/call
# once (222µs+94µs) by Foswiki::Prefs::finish at line 115 of /var/www/foswiki11/lib/Foswiki/Prefs.pm | ||||
61 | 93 | 16µs | my $this = shift; | ||
62 | 93 | 107µs | undef $this->{'final'}; | ||
63 | 93 | 70µs | if ( $this->{'levels'} ) { | ||
64 | foreach my $back ( @{ $this->{'levels'} } ) { | ||||
65 | 142 | 367µs | 142 | 281µs | $back->finish(); # spent 279µs making 141 calls to Foswiki::Prefs::TopicRAM::finish, avg 2µs/call
# spent 2µs making 1 call to Foswiki::Prefs::HASH::finish |
66 | } | ||||
67 | } | ||||
68 | 93 | 79µs | undef $this->{'levels'}; | ||
69 | 93 | 171µs | undef $this->{'map'}; | ||
70 | } | ||||
71 | |||||
72 | =begin TML | ||||
73 | |||||
74 | ---++ ObjectMethod size() -> $size | ||||
75 | |||||
76 | Returns the size of the stack in number of levels. | ||||
77 | |||||
78 | =cut | ||||
79 | |||||
80 | # spent 382µs within Foswiki::Prefs::Stack::size which was called 156 times, avg 2µs/call:
# 91 times (220µs+0s) by Foswiki::Prefs::_pushWebInStack at line 158 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 2µs/call
# 51 times (102µs+0s) by Foswiki::Prefs::Web::isInTopOfStack at line 68 of /var/www/foswiki11/lib/Foswiki/Prefs/Web.pm, avg 2µs/call
# 7 times (43µs+0s) by Foswiki::Prefs::setPluginPreferences at line 333 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 6µs/call
# 7 times (16µs+0s) by Foswiki::Prefs::pushTopicContext at line 269 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 2µs/call | ||||
81 | 156 | 713µs | return scalar @{ $_[0]->{levels} }; | ||
82 | } | ||||
83 | |||||
84 | =begin TML | ||||
85 | |||||
86 | ---++ ObjectMethod backAtLevel($level) -> $back | ||||
87 | |||||
88 | Returns the backend object corresponding to $level. If $level is negative, | ||||
89 | consider that number from the top of the stack. -1 means the top element. | ||||
90 | |||||
91 | =cut | ||||
92 | |||||
93 | # spent 1.36ms within Foswiki::Prefs::Stack::backAtLevel which was called 659 times, avg 2µs/call:
# 570 times (1.19ms+0s) by Foswiki::Prefs::getPreference at line 442 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 2µs/call
# 83 times (154µs+0s) by Foswiki::Prefs::getPreference at line 450 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 2µs/call
# 6 times (19µs+0s) by Foswiki::Prefs::popTopicContext at line 313 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 3µs/call | ||||
94 | 659 | 2.65ms | return $_[0]->{levels}->[ $_[1] ]; | ||
95 | } | ||||
96 | |||||
97 | =begin TML | ||||
98 | |||||
99 | ---++ ObjectMethod finalizedBefore($pref, $level) -> $boolean | ||||
100 | |||||
101 | Returns true if $pref was finalized somewhere earlier than $level. If $pref is | ||||
102 | finalized *in* $level or it's not finalized, returns true. | ||||
103 | |||||
104 | =cut | ||||
105 | |||||
106 | # spent 2.20ms within Foswiki::Prefs::Stack::finalizedBefore which was called 570 times, avg 4µs/call:
# 570 times (2.20ms+0s) by Foswiki::Prefs::getPreference at line 443 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 4µs/call | ||||
107 | 570 | 402µs | my ( $this, $key, $level ) = @_; | ||
108 | 570 | 492µs | $level += @{ $this->{levels} } if $level < 0; | ||
109 | 570 | 1.98ms | return exists $this->{final}{$key} && $this->{final}{$key} < $level; | ||
110 | } | ||||
111 | |||||
112 | =begin TML | ||||
113 | |||||
114 | ---++ ObjectMethod finalized($pref) -> $boolean | ||||
115 | |||||
116 | Returns true if $pref in finalized. | ||||
117 | |||||
118 | =cut | ||||
119 | |||||
120 | # spent 52µs within Foswiki::Prefs::Stack::finalized which was called 8 times, avg 7µs/call:
# 8 times (52µs+0s) by Foswiki::Prefs::setSessionPreferences at line 397 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 7µs/call | ||||
121 | 8 | 15µs | my ( $this, $key ) = @_; | ||
122 | 8 | 65µs | return exists $this->{final}{$key}; | ||
123 | } | ||||
124 | |||||
125 | =begin TML | ||||
126 | |||||
127 | ---++ ObjectMethod prefs() -> @prefs | ||||
128 | |||||
129 | Returns a list with the name of all defined prefs in the stack. | ||||
130 | |||||
131 | =cut | ||||
132 | |||||
133 | sub prefs { | ||||
134 | return keys %{ $_[0]->{'map'} }; | ||||
135 | } | ||||
136 | |||||
137 | =begin TML | ||||
138 | |||||
139 | ---++ ObjectMethod prefIsDefined($pref) -> $boolean | ||||
140 | |||||
141 | Returns true if $pref is defined somewhere in the stack. | ||||
142 | |||||
143 | =cut | ||||
144 | |||||
145 | # spent 1.22ms within Foswiki::Prefs::Stack::prefIsDefined which was called 570 times, avg 2µs/call:
# 570 times (1.22ms+0s) by Foswiki::Prefs::getPreference at line 446 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 2µs/call | ||||
146 | 570 | 1.82ms | return exists $_[0]->{'map'}{ $_[1] }; | ||
147 | } | ||||
148 | |||||
149 | =begin TML | ||||
150 | |||||
151 | ---++ ObjectMethod insert($type, $pref, $value) -> $num | ||||
152 | |||||
153 | Define preference named $pref of type $type as $value. $type can be 'Local' or | ||||
154 | 'Set'. | ||||
155 | |||||
156 | Returns the number of inserted preferences (0 or 1). | ||||
157 | |||||
158 | =cut | ||||
159 | |||||
160 | # spent 1.00ms (463µs+538µs) within Foswiki::Prefs::Stack::insert which was called 48 times, avg 21µs/call:
# 40 times (307µs+353µs) by Foswiki::Prefs::pushTopicContext at line 285 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 17µs/call
# 8 times (156µs+184µs) by Foswiki::Prefs::setSessionPreferences at line 398 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 43µs/call | ||||
161 | 48 | 15µs | my $this = shift; | ||
162 | |||||
163 | 48 | 29µs | my $back = $this->{levels}->[-1]; | ||
164 | 48 | 81µs | 48 | 538µs | my $num = $back->insert(@_); # spent 538µs making 48 calls to Foswiki::Prefs::HASH::insert, avg 11µs/call |
165 | |||||
166 | 48 | 29µs | my $key = $_[1]; | ||
167 | 48 | 47µs | $this->{'map'}{$key} = '' unless exists $this->{'map'}{$key}; | ||
168 | |||||
169 | 48 | 24µs | my $level = $#{ $this->{levels} }; | ||
170 | 48 | 86µs | vec( $this->{'map'}{$key}, $level, 1 ) = 1; | ||
171 | |||||
172 | 48 | 144µs | return $num; | ||
173 | } | ||||
174 | |||||
175 | =begin TML | ||||
176 | |||||
177 | ---++ ObjectMethod newLevel($back, $prefix) | ||||
178 | |||||
179 | Pushes all preferences in $back on the stack, except for the finalized ones. | ||||
180 | Optionally $prefix preferences name in the index. This feature is used by | ||||
181 | plugins: A preference PREF defined in MyPlugin topic should be referenced by | ||||
182 | MYPLUGIN_PREF. In this example $prefix is MYPLUGIN_. | ||||
183 | |||||
184 | =cut | ||||
185 | |||||
186 | # spent 11.4ms (10.2+1.24) within Foswiki::Prefs::Stack::newLevel which was called 130 times, avg 88µs/call:
# 92 times (7.97ms+941µs) by Foswiki::Prefs::_pushWebInStack at line 164 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 97µs/call
# 14 times (979µs+109µs) by Foswiki::Prefs::pushTopicContext at line 279 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 78µs/call
# 7 times (595µs+93µs) by Foswiki::Prefs::setPluginPreferences at line 332 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 98µs/call
# 7 times (90µs+42µs) by Foswiki::Prefs::pushTopicContext at line 283 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 19µs/call
# 7 times (80µs+26µs) by Foswiki::Prefs::pushTopicContext at line 282 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 15µs/call
# once (298µs+16µs) by Foswiki::Prefs::loadDefaultPreferences at line 363 of /var/www/foswiki11/lib/Foswiki/Prefs.pm
# once (171µs+10µs) by Foswiki::Prefs::loadSitePreferences at line 380 of /var/www/foswiki11/lib/Foswiki/Prefs.pm
# once (10µs+3µs) by Foswiki::Prefs::setUserPreferences at line 348 of /var/www/foswiki11/lib/Foswiki/Prefs.pm | ||||
187 | 130 | 108µs | my ( $this, $back, $prefix ) = @_; | ||
188 | |||||
189 | 130 | 175µs | push @{ $this->{levels} }, $back; | ||
190 | 130 | 122µs | my $level = $#{ $this->{levels} }; | ||
191 | 130 | 79µs | $prefix ||= ''; | ||
192 | 130 | 1.62ms | 130 | 763µs | foreach ( map { $prefix . $_ } $back->prefs ) { # spent 745µs making 123 calls to Foswiki::Prefs::TopicRAM::prefs, avg 6µs/call
# spent 18µs making 7 calls to Foswiki::Prefs::HASH::prefs, avg 3µs/call |
193 | 1962 | 882µs | next if exists $this->{final}{$_}; | ||
194 | 1715 | 1.78ms | $this->{'map'}{$_} = '' unless exists $this->{'map'}{$_}; | ||
195 | 1715 | 2.55ms | vec( $this->{'map'}{$_}, $level, 1 ) = 1; | ||
196 | } | ||||
197 | |||||
198 | 130 | 1.06ms | 130 | 478µs | my @finalPrefs = split /[,\s]+/, ( $back->get('FINALPREFERENCES') || '' ); # spent 454µs making 123 calls to Foswiki::Prefs::TopicRAM::get, avg 4µs/call
# spent 24µs making 7 calls to Foswiki::Prefs::HASH::get, avg 3µs/call |
199 | 130 | 143µs | foreach (@finalPrefs) { | ||
200 | 595 | 748µs | $this->{final}{$_} = $level | ||
201 | unless exists $this->{final}{$_}; | ||||
202 | } | ||||
203 | |||||
204 | 130 | 533µs | return $back; | ||
205 | } | ||||
206 | |||||
207 | =begin TML | ||||
208 | |||||
209 | ---++ ObjectMethod getDefinitionLevel($pref) -> $level | ||||
210 | |||||
211 | Returns the $level in which $pref was defined or undef if it's not defined. | ||||
212 | |||||
213 | =cut | ||||
214 | |||||
215 | # spent 944µs (507+437) within Foswiki::Prefs::Stack::getDefinitionLevel which was called 83 times, avg 11µs/call:
# 83 times (507µs+437µs) by Foswiki::Prefs::getPreference at line 447 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 11µs/call | ||||
216 | 83 | 50µs | my ( $this, $pref ) = @_; | ||
217 | return | ||||
218 | 83 | 411µs | 83 | 437µs | exists $this->{'map'}{$pref} ? _getLevel( $this->{'map'}{$pref} ) : undef; # spent 437µs making 83 calls to Foswiki::Prefs::Stack::_getLevel, avg 5µs/call |
219 | } | ||||
220 | |||||
221 | # Used to get the level of the highest 1, given a bitstring map. | ||||
222 | sub _getLevel { | ||||
223 | 941 | 337µs | my $map = shift; | ||
224 | return | ||||
225 | 941 | 8.54ms | int( log( ord( substr( $map, -1 ) ) ) / log(2) ) + | ||
226 | ( ( length($map) - 1 ) * 8 ); | ||||
227 | } | ||||
228 | |||||
229 | =begin TML | ||||
230 | |||||
231 | ---++ ObjectMethod getPreference($pref [, $level] ) -> $value | ||||
232 | |||||
233 | Returns the $value of $pref, considering the stack rules (values in higher | ||||
234 | levels overrides those in lower levels). | ||||
235 | |||||
236 | Optionally consider preferences at most $level. This is usefull to get a | ||||
237 | preference of Web if the stack has Web/Subweb. This makes it possible to use | ||||
238 | the same stack for Web and Web/Subweb. | ||||
239 | |||||
240 | =cut | ||||
241 | |||||
242 | # spent 21.2ms (16.0+5.14) within Foswiki::Prefs::Stack::getPreference which was called 861 times, avg 25µs/call:
# 861 times (16.0ms+5.14ms) by Foswiki::Prefs::Web::get at line 110 of /var/www/foswiki11/lib/Foswiki/Prefs/Web.pm, avg 25µs/call | ||||
243 | 861 | 472µs | my ( $this, $key, $level ) = @_; | ||
244 | 861 | 648µs | my $map = $this->{'map'}{$key}; | ||
245 | 861 | 154µs | return unless defined $map; | ||
246 | 858 | 307µs | if ( defined $level ) { | ||
247 | 858 | 2.44ms | my $mask = | ||
248 | ( chr(0xFF) x int( $level / 8 ) ) | ||||
249 | . chr( ( 2**( ( $level % 8 ) + 1 ) ) - 1 ); | ||||
250 | 858 | 490µs | $map &= $mask; | ||
251 | 858 | 1.18ms | substr( $map, -1 ) = '' | ||
252 | while length($map) > 0 && ord( substr( $map, -1 ) ) == 0; | ||||
253 | 858 | 368µs | return unless length($map) > 0; | ||
254 | } | ||||
255 | 858 | 8.33ms | 1716 | 5.14ms | return $this->{levels}->[ _getLevel($map) ]->get($key); # spent 3.01ms making 858 calls to Foswiki::Prefs::Stack::_getLevel, avg 4µs/call
# spent 2.13ms making 858 calls to Foswiki::Prefs::TopicRAM::get, avg 2µs/call |
256 | } | ||||
257 | |||||
258 | =begin TML | ||||
259 | |||||
260 | ---++ ObjectMethod clone($level ) -> $stack | ||||
261 | |||||
262 | This constructs a new $stack object as a clone of this one, up to the given | ||||
263 | $level. If no $level is given, the resulting object is an extac copy. | ||||
264 | |||||
265 | =cut | ||||
266 | |||||
267 | # spent 3.91ms (1.23+2.68) within Foswiki::Prefs::Stack::clone which was called 36 times, avg 109µs/call:
# 36 times (1.23ms+2.68ms) by Foswiki::Prefs::Web::cloneStack at line 97 of /var/www/foswiki11/lib/Foswiki/Prefs/Web.pm, avg 109µs/call | ||||
268 | 36 | 20µs | my ( $this, $level ) = @_; | ||
269 | |||||
270 | 36 | 44µs | 36 | 229µs | my $clone = $this->new(); # spent 229µs making 36 calls to Foswiki::Prefs::Stack::new, avg 6µs/call |
271 | 36 | 585µs | $clone->{'map'} = { %{ $this->{'map'} } }; | ||
272 | 36 | 63µs | $clone->{'levels'} = [ @{ $this->{levels} } ]; | ||
273 | 36 | 155µs | $clone->{'final'} = { %{ $this->{final} } }; | ||
274 | 36 | 127µs | 36 | 2.45ms | $clone->restore($level) if defined $level; # spent 2.45ms making 36 calls to Foswiki::Prefs::Stack::restore, avg 68µs/call |
275 | |||||
276 | 36 | 118µs | return $clone; | ||
277 | } | ||||
278 | |||||
279 | =begin TML | ||||
280 | |||||
281 | ---++ ObjectMethod restore($level) | ||||
282 | |||||
283 | Restores tha stack to the state it was in the given $level. | ||||
284 | |||||
285 | =cut | ||||
286 | |||||
287 | # spent 5.66ms within Foswiki::Prefs::Stack::restore which was called 42 times, avg 135µs/call:
# 36 times (2.45ms+0s) by Foswiki::Prefs::Stack::clone at line 274, avg 68µs/call
# 6 times (3.20ms+0s) by Foswiki::Prefs::popTopicContext at line 308 of /var/www/foswiki11/lib/Foswiki/Prefs.pm, avg 534µs/call | ||||
288 | 42 | 43µs | my ( $this, $level ) = @_; | ||
289 | |||||
290 | 42 | 332µs | my @keys = grep { $this->{final}{$_} > $level } keys %{ $this->{final} }; | ||
291 | 42 | 34µs | delete @{ $this->{final} }{@keys}; | ||
292 | 42 | 102µs | splice @{ $this->{levels} }, $level + 1; | ||
293 | |||||
294 | 42 | 159µs | my $mask = | ||
295 | ( chr(0xFF) x int( $level / 8 ) ) | ||||
296 | . chr( ( 2**( ( $level % 8 ) + 1 ) ) - 1 ); | ||||
297 | 42 | 645µs | foreach my $p ( keys %{ $this->{'map'} } ) { | ||
298 | 2024 | 1.01ms | $this->{'map'}{$p} &= $mask; | ||
299 | |||||
300 | 2024 | 1.98ms | while ( length( $this->{'map'}{$p} ) > 0 | ||
301 | && ord( substr( $this->{'map'}{$p}, -1 ) ) == 0 ) | ||||
302 | { | ||||
303 | 139 | 186µs | substr( $this->{'map'}{$p}, -1 ) = ''; | ||
304 | } | ||||
305 | |||||
306 | 2024 | 1.26ms | delete $this->{'map'}{$p} if length( $this->{'map'}{$p} ) == 0; | ||
307 | } | ||||
308 | } | ||||
309 | |||||
310 | 1 | 2µs | 1; | ||
311 | __END__ |