Filename | /usr/local/src/github.com/foswiki/core/lib/Foswiki/Prefs.pm |
Statements | Executed 57157 statements in 262ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
6951 | 9 | 3 | 144ms | 144ms | setInternalPreferences | Foswiki::Prefs::
7613 | 24 | 11 | 79.2ms | 102ms | getPreference | Foswiki::Prefs::
21 | 2 | 2 | 8.35ms | 48.2ms | pushTopicContext | Foswiki::Prefs::
20 | 1 | 1 | 4.10ms | 34.2ms | popTopicContext | Foswiki::Prefs::
69 | 1 | 1 | 3.19ms | 60.8s | loadPreferences | Foswiki::Prefs::
1 | 1 | 1 | 1.88ms | 2.32ms | BEGIN@70 | Foswiki::Prefs::
21 | 2 | 2 | 1.57ms | 6.05ms | setSessionPreferences | Foswiki::Prefs::
48 | 6 | 1 | 1.42ms | 61.0s | _getBackend | Foswiki::Prefs::
34 | 1 | 1 | 722µs | 60.7s | _getWebPrefsObj | Foswiki::Prefs::
1 | 1 | 1 | 613µs | 1.59ms | BEGIN@69 | Foswiki::Prefs::
1 | 1 | 1 | 608µs | 674µs | BEGIN@71 | Foswiki::Prefs::
1 | 1 | 1 | 279µs | 880µs | finish | Foswiki::Prefs::
3 | 1 | 1 | 166µs | 60.7s | _pushWebInStack | Foswiki::Prefs::
1 | 1 | 1 | 104µs | 1.99ms | new | Foswiki::Prefs::
1 | 1 | 1 | 67µs | 282ms | loadDefaultPreferences | Foswiki::Prefs::
1 | 1 | 1 | 45µs | 6.00ms | loadSitePreferences | Foswiki::Prefs::
1 | 1 | 1 | 29µs | 38µs | BEGIN@2 | Foswiki::
1 | 1 | 1 | 23µs | 7.72ms | setUserPreferences | Foswiki::Prefs::
1 | 1 | 1 | 19µs | 44µs | BEGIN@3 | Foswiki::
1 | 1 | 1 | 18µs | 63µs | BEGIN@68 | Foswiki::Prefs::
1 | 1 | 1 | 10µs | 10µs | BEGIN@72 | Foswiki::Prefs::
0 | 0 | 0 | 0s | 0s | setPluginPreferences | Foswiki::Prefs::
0 | 0 | 0 | 0s | 0s | stringify | Foswiki::Prefs::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # See bottom of file for license and copyright information | ||||
2 | 2 | 50µs | 2 | 48µs | # spent 38µs (29+10) within Foswiki::BEGIN@2 which was called:
# once (29µs+10µs) by Foswiki::BEGIN@610 at line 2 # spent 38µs making 1 call to Foswiki::BEGIN@2
# spent 10µs making 1 call to strict::import |
3 | 2 | 125µs | 2 | 70µs | # spent 44µs (19+25) within Foswiki::BEGIN@3 which was called:
# once (19µs+25µs) by Foswiki::BEGIN@610 at line 3 # spent 44µs making 1 call to Foswiki::BEGIN@3
# spent 25µs making 1 call to warnings::import |
4 | |||||
5 | =begin TML | ||||
6 | |||||
7 | ---+ package Foswiki::Prefs | ||||
8 | |||||
9 | Preferences are set in topics, using either 'Set' lines embedded in the | ||||
10 | topic text, or via PREFERENCE meta-data attached to the topic. A preference | ||||
11 | value has four _scopes_: | ||||
12 | * _Global_ scope | ||||
13 | * _Local_ scope | ||||
14 | * _Web_ scope | ||||
15 | * _Topic_ scope | ||||
16 | |||||
17 | In _global_ scope, the value of a preference is determined by examining | ||||
18 | settings of the variable at different levels; default preferences, site level, | ||||
19 | parent web level, web level, user level, and topic level. To determine a | ||||
20 | preference value in global scope, you have to know what topic the topic is | ||||
21 | referenced in, to provide the scope for the request. | ||||
22 | |||||
23 | A preference may be optionally defined in _Local_ scope, in which case the | ||||
24 | topic definition of the variable is always taken when it is referenced in the | ||||
25 | topic where it is defined. This is a special case to deal with the case where a | ||||
26 | preference has to have a different value in the defining topic. | ||||
27 | |||||
28 | Values in global and local scope are accessed using =getPreference=/ | ||||
29 | |||||
30 | _Web_ scope is used by web access controls. Subwebs inherint access controls | ||||
31 | from parent webs and only from parent webs. Global and Local scopes are | ||||
32 | disconsidered. | ||||
33 | |||||
34 | The final scope is _topic_ scope. In this scope, the value of the preference is | ||||
35 | taken directly from the contents of the topic, and is not overridden by wider | ||||
36 | scopes. Topic scope is used for topic access controls. | ||||
37 | |||||
38 | Because the highest cost in evaluating preferences is reading the individual | ||||
39 | topics, preferences read from a topic are cached. | ||||
40 | |||||
41 | An object of type Foswiki::Prefs is a singleton that provides an interface to | ||||
42 | this cache. Normally the cache is repopulated for each request, though it would | ||||
43 | be feasible to cache it on disc if some invalidation mechanism were available | ||||
44 | to deal with topic changes. | ||||
45 | |||||
46 | This mechanism is composed by a front-end (implemented by this class) that | ||||
47 | deals with preferences logic and back-end objects that provide access to | ||||
48 | preferences values. There is one back-end for each topic (Web preferences are | ||||
49 | back-ends correspondind to the WebPreferences topic). Additionaly, there is a | ||||
50 | back-end object for session preferences. Each context has its own session | ||||
51 | preferences and thus its own session back-end object. | ||||
52 | |||||
53 | Preferences are like a stack: there are many levels and higher levels have | ||||
54 | precedence over lower levels. It's also needed to push a context and pop to the | ||||
55 | earlier state. It would be easy to implement this stack, but then we would have | ||||
56 | a problem: to get the value of a preference we would need to scan each level | ||||
57 | and it's slow, so we need some fast mechanism to know in which level a | ||||
58 | preference is defined. Or we could copy the values from lower leves to higher | ||||
59 | ones and override the preferences defined at that level. This later approach | ||||
60 | wastes memory. This implementation picks the former and we use bitstrings and | ||||
61 | some maths to accomplish that. It's also flexible and it doesn't matter how | ||||
62 | preferences are stored. | ||||
63 | |||||
64 | =cut | ||||
65 | |||||
66 | package Foswiki::Prefs; | ||||
67 | |||||
68 | 2 | 48µs | 2 | 108µs | # spent 63µs (18+45) within Foswiki::Prefs::BEGIN@68 which was called:
# once (18µs+45µs) by Foswiki::BEGIN@610 at line 68 # spent 63µs making 1 call to Foswiki::Prefs::BEGIN@68
# spent 45µs making 1 call to Assert::import |
69 | 2 | 194µs | 1 | 1.59ms | # spent 1.59ms (613µs+974µs) within Foswiki::Prefs::BEGIN@69 which was called:
# once (613µs+974µs) by Foswiki::BEGIN@610 at line 69 # spent 1.59ms making 1 call to Foswiki::Prefs::BEGIN@69 |
70 | 2 | 175µs | 1 | 2.32ms | # spent 2.32ms (1.88+441µs) within Foswiki::Prefs::BEGIN@70 which was called:
# once (1.88ms+441µs) by Foswiki::BEGIN@610 at line 70 # spent 2.32ms making 1 call to Foswiki::Prefs::BEGIN@70 |
71 | 2 | 140µs | 1 | 674µs | # spent 674µs (608+66) within Foswiki::Prefs::BEGIN@71 which was called:
# once (608µs+66µs) by Foswiki::BEGIN@610 at line 71 # spent 674µs making 1 call to Foswiki::Prefs::BEGIN@71 |
72 | 2 | 2.79ms | 1 | 10µs | # spent 10µs within Foswiki::Prefs::BEGIN@72 which was called:
# once (10µs+0s) by Foswiki::BEGIN@610 at line 72 # spent 10µs making 1 call to Foswiki::Prefs::BEGIN@72 |
73 | |||||
74 | =begin TML | ||||
75 | |||||
76 | ---++ ClassMethod new( $session ) | ||||
77 | |||||
78 | Creates a new Prefs object. | ||||
79 | |||||
80 | =cut | ||||
81 | |||||
82 | # spent 1.99ms (104µs+1.89) within Foswiki::Prefs::new which was called:
# once (104µs+1.89ms) by Foswiki::new at line 1691 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm | ||||
83 | 6 | 101µs | my ( $proto, $session ) = @_; | ||
84 | my $class = ref($proto) || $proto; | ||||
85 | 1 | 23µs | my $this = { # spent 23µs making 1 call to Foswiki::Prefs::Stack::new | ||
86 | 'main' => Foswiki::Prefs::Stack->new(), # Main preferences stack | ||||
87 | 'paths' => {}, # Map paths to backend objects | ||||
88 | 'contexts' => [], # Store the main levels corresponding to contexts | ||||
89 | 'prefix' => [], # Map level => prefix uesed | ||||
90 | # (plugins prefix prefs with PLUGINNAME_) | ||||
91 | 'webprefs' => {}, # Foswiki::Prefs::Web objs, used to get web prefs | ||||
92 | 'internals' => {}, # Store internal preferences | ||||
93 | 'session' => $session, | ||||
94 | }; | ||||
95 | |||||
96 | eval "use $Foswiki::cfg{Store}{PrefsBackend} ()"; # spent 132µs executing statements in string eval # includes 753µs spent executing 1 call to 1 sub defined therein. | ||||
97 | die $@ if $@; | ||||
98 | |||||
99 | return bless $this, $class; | ||||
100 | } | ||||
101 | |||||
102 | =begin TML | ||||
103 | |||||
104 | ---++ ObjectMethod finish() | ||||
105 | Break circular references. | ||||
106 | |||||
107 | =cut | ||||
108 | |||||
109 | # Note to developers; please undef *all* fields in the object explicitly, | ||||
110 | # whether they are references or not. That way this method is "golden | ||||
111 | # documentation" of the live fields in the object. | ||||
112 | # spent 880µs (279+601) within Foswiki::Prefs::finish which was called:
# once (279µs+601µs) by Foswiki::finish at line 2100 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm | ||||
113 | 11 | 140µs | my $this = shift; | ||
114 | |||||
115 | 1 | 299µs | $this->{main}->finish() if $this->{main}; # spent 299µs making 1 call to Foswiki::Prefs::Stack::finish | ||
116 | undef $this->{main}; | ||||
117 | undef $this->{prefix}; | ||||
118 | undef $this->{session}; | ||||
119 | undef $this->{contexts}; | ||||
120 | 1 | 9µs | if ( $this->{paths} ) { | ||
121 | 1 | 2µs | foreach my $back ( values %{ $this->{paths} } ) { | ||
122 | 7 | 77µs | 7 | 102µs | $back->finish(); # spent 102µs making 7 calls to Foswiki::Prefs::TopicRAM::finish, avg 15µs/call |
123 | } | ||||
124 | } | ||||
125 | undef $this->{paths}; | ||||
126 | 1 | 8µs | if ( $this->{webprefs} ) { | ||
127 | 1 | 2µs | foreach my $webStack ( values %{ $this->{webprefs} } ) { | ||
128 | 3 | 26µs | 3 | 201µs | $webStack->finish(); # spent 201µs making 3 calls to Foswiki::Prefs::Web::finish, avg 67µs/call |
129 | } | ||||
130 | } | ||||
131 | undef $this->{webprefs}; | ||||
132 | undef $this->{internals}; | ||||
133 | } | ||||
134 | |||||
135 | # Get a backend object corresponding to the given $web,$topic | ||||
136 | # spent 61.0s (1.42ms+61.0) within Foswiki::Prefs::_getBackend which was called 48 times, avg 1.27s/call:
# 21 times (495µs+7.42ms) by Foswiki::Prefs::pushTopicContext at line 279, avg 377µs/call
# 21 times (646µs+6.08ms) by Foswiki::Prefs::pushTopicContext at line 276, avg 320µs/call
# 3 times (121µs+60.7s) by Foswiki::Prefs::_pushWebInStack at line 161, avg 20.2s/call
# once (66µs+280ms) by Foswiki::Prefs::loadDefaultPreferences at line 358
# once (42µs+7.60ms) by Foswiki::Prefs::setUserPreferences at line 344
# once (50µs+5.32ms) by Foswiki::Prefs::loadSitePreferences at line 376 | ||||
137 | 240 | 1.24ms | my $this = shift; | ||
138 | |||||
139 | 48 | 2.62ms | my $metaObject = Foswiki::Meta->new( $this->{session}, @_ ); # spent 2.62ms making 48 calls to Foswiki::Meta::new, avg 55µs/call | ||
140 | 48 | 575µs | my $path = $metaObject->getPath(); # spent 575µs making 48 calls to Foswiki::Meta::getPath, avg 12µs/call | ||
141 | 7 | 89µs | unless ( exists $this->{paths}{$path} ) { | ||
142 | 7 | 61.0s | $this->{paths}{$path} = # spent 61.0s making 7 calls to Foswiki::Prefs::TopicRAM::new, avg 8.72s/call | ||
143 | $Foswiki::cfg{Store}{PrefsBackend}->new($metaObject); | ||||
144 | } | ||||
145 | return $this->{paths}{$path}; | ||||
146 | } | ||||
147 | |||||
148 | # Given a (sub)web and a stack object, push the (sub)web on the stack, | ||||
149 | # considering that part of the (sub)web may already be in the stack. This is | ||||
150 | # used to build, for example, Web/Subweb/WebA stack based on Web/Subweb or Web | ||||
151 | # stack. | ||||
152 | # spent 60.7s (166µs+60.7) within Foswiki::Prefs::_pushWebInStack which was called 3 times, avg 20.2s/call:
# 3 times (166µs+60.7s) by Foswiki::Prefs::_getWebPrefsObj at line 197, avg 20.2s/call | ||||
153 | 18 | 81µs | my ( $this, $stack, $web ) = @_; | ||
154 | my @webPath = split( /[\/\.]+/, $web ); | ||||
155 | my $subWeb = ''; | ||||
156 | 3 | 29µs | $subWeb = join '/', splice @webPath, 0, $stack->size(); # spent 29µs making 3 calls to Foswiki::Prefs::Stack::size, avg 10µs/call | ||
157 | my $back; | ||||
158 | foreach (@webPath) { | ||||
159 | 12 | 79µs | $subWeb .= '/' if $subWeb; | ||
160 | $subWeb .= $_; | ||||
161 | 3 | 60.7s | $back = $this->_getBackend( $subWeb, $Foswiki::cfg{WebPrefsTopicName} ); # spent 60.7s making 3 calls to Foswiki::Prefs::_getBackend, avg 20.2s/call | ||
162 | 3 | 923µs | $stack->newLevel($back); # spent 923µs making 3 calls to Foswiki::Prefs::Stack::newLevel, avg 308µs/call | ||
163 | } | ||||
164 | } | ||||
165 | |||||
166 | # Returns a Foswiki::Prefs::Web object. It consider the already existing | ||||
167 | # objects and build a new one only if it doesn't exist. And even if it doesn't | ||||
168 | # exist, consider existing ones to speedup the construction. Example: | ||||
169 | # Web/SubWeb already exists and we want Web/Subweb/WebA. Then we just push | ||||
170 | # WebA. If, instead, Web/Subweb/WebB exists, then we clone tha stack up to | ||||
171 | # Web/Subweb and push WebA on it. | ||||
172 | # spent 60.7s (722µs+60.7) within Foswiki::Prefs::_getWebPrefsObj which was called 34 times, avg 1.79s/call:
# 34 times (722µs+60.7s) by Foswiki::Prefs::loadPreferences at line 234, avg 1.79s/call | ||||
173 | 132 | 415µs | my ( $this, $web ) = @_; | ||
174 | my ( $stack, $level ); | ||||
175 | |||||
176 | 31 | 263µs | if ( exists $this->{webprefs}{$web} ) { | ||
177 | return $this->{webprefs}{$web}; | ||||
178 | } | ||||
179 | |||||
180 | my $part; | ||||
181 | 3 | 89µs | $stack = Foswiki::Prefs::Stack->new(); # spent 89µs making 3 calls to Foswiki::Prefs::Stack::new, avg 30µs/call | ||
182 | my @path = split /[\/\.]+/, $web; | ||||
183 | my @websToAdd = ( pop @path ); | ||||
184 | while ( @path > 0 ) { | ||||
185 | $part = join( '/', @path ); | ||||
186 | if ( exists $this->{webprefs}{$part} ) { | ||||
187 | my $base = $this->{webprefs}{$part}; | ||||
188 | $stack = | ||||
189 | $base->isInTopOfStack() | ||||
190 | ? $base->stack() | ||||
191 | : $base->cloneStack( scalar(@path) - 1 ); | ||||
192 | last; | ||||
193 | } | ||||
194 | unshift @websToAdd, pop @path; | ||||
195 | } | ||||
196 | |||||
197 | 3 | 60.7s | $this->_pushWebInStack( $stack, $web ); # spent 60.7s making 3 calls to Foswiki::Prefs::_pushWebInStack, avg 20.2s/call | ||
198 | $part = join( '/', @path ); | ||||
199 | $level = scalar @path; | ||||
200 | foreach (@websToAdd) { | ||||
201 | 9 | 84µs | $part .= '/' if $part; | ||
202 | $part .= $_; | ||||
203 | 3 | 102µs | $this->{webprefs}{$part} = Foswiki::Prefs::Web->new( $stack, $level++ ); # spent 102µs making 3 calls to Foswiki::Prefs::Web::new, avg 34µs/call | ||
204 | } | ||||
205 | return $this->{webprefs}{$web}; | ||||
206 | } | ||||
207 | |||||
208 | =begin TML | ||||
209 | |||||
210 | ---++ ObjectMethod loadPreferences( $topicObject ) -> $back | ||||
211 | |||||
212 | Invoked from Foswiki::Meta to load the preferences into the preferences | ||||
213 | cache. used as part of the lazy-loading of preferences. | ||||
214 | |||||
215 | Web preferences are loaded from the {WebPrefsTopicName}. | ||||
216 | |||||
217 | =cut | ||||
218 | |||||
219 | # spent 60.8s (3.19ms+60.8) within Foswiki::Prefs::loadPreferences which was called 69 times, avg 881ms/call:
# 69 times (3.19ms+60.8s) by Foswiki::Meta::getPreference at line 659 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Meta.pm, avg 881ms/call | ||||
220 | 345 | 1.71ms | my ( $this, $topicObject ) = @_; | ||
221 | |||||
222 | 69 | 842µs | my $path = $topicObject->getPath(); # spent 842µs making 69 calls to Foswiki::Meta::getPath, avg 12µs/call | ||
223 | |||||
224 | # $topicObject->session->logger->log( 'debug', | ||||
225 | # "Loading preferences for $path\n" ) | ||||
226 | # if DEBUG; | ||||
227 | |||||
228 | my $obj; | ||||
229 | |||||
230 | 69 | 1.01ms | 103 | 828µs | if ( $topicObject->topic() ) { # spent 540µs making 69 calls to Foswiki::Meta::topic, avg 8µs/call
# spent 288µs making 34 calls to Foswiki::Meta::web, avg 8µs/call |
231 | 35 | 34.8ms | $obj = $Foswiki::cfg{Store}{PrefsBackend}->new($topicObject); # spent 34.8ms making 35 calls to Foswiki::Prefs::TopicRAM::new, avg 993µs/call | ||
232 | } | ||||
233 | elsif ( $topicObject->web() ) { | ||||
234 | 68 | 60.7s | $obj = $this->_getWebPrefsObj( $topicObject->web() ); # spent 60.7s making 34 calls to Foswiki::Prefs::_getWebPrefsObj, avg 1.79s/call
# spent 235µs making 34 calls to Foswiki::Meta::web, avg 7µs/call | ||
235 | } | ||||
236 | elsif ( $Foswiki::cfg{LocalSitePreferences} ) { | ||||
237 | my ( $web, $topic ) = | ||||
238 | $this->{session} | ||||
239 | ->normalizeWebTopicName( undef, $Foswiki::cfg{LocalSitePreferences} ); | ||||
240 | |||||
241 | # Use the site preferences | ||||
242 | $obj = $this->_getBackend( $web, $topic ); | ||||
243 | } | ||||
244 | |||||
245 | return $obj; | ||||
246 | } | ||||
247 | |||||
248 | =begin TML | ||||
249 | |||||
250 | ---++ ObjectMethod pushTopicContext( $web, $topic ) | ||||
251 | |||||
252 | Reconfigures the preferences so that general preference values appear | ||||
253 | to come from $web.$topic. The topic context can be popped again using | ||||
254 | popTopicContext. | ||||
255 | |||||
256 | =cut | ||||
257 | |||||
258 | # spent 48.2ms (8.35+39.9) within Foswiki::Prefs::pushTopicContext which was called 21 times, avg 2.30ms/call:
# 20 times (7.97ms+27.7ms) by Foswiki::INCLUDE at line 201 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm, avg 1.79ms/call
# once (385µs+12.1ms) by Foswiki::new at line 1891 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm | ||||
259 | 273 | 4.53ms | my ( $this, $web, $topic ) = @_; | ||
260 | |||||
261 | my $stack = $this->{main}; | ||||
262 | my %internals; | ||||
263 | 563 | 949µs | while ( my ( $k, $v ) = each %{ $this->{internals} } ) { | ||
264 | $internals{$k} = $v; | ||||
265 | } | ||||
266 | push( | ||||
267 | 21 | 30µs | 21 | 200µs | @{ $this->{contexts} }, # spent 200µs making 21 calls to Foswiki::Prefs::Stack::size, avg 10µs/call |
268 | { internals => \%internals, level => $stack->size() - 1 } | ||||
269 | ); | ||||
270 | my @webPath = split( /[\/\.]+/, $web ); | ||||
271 | my $subWeb = ''; | ||||
272 | my $back; | ||||
273 | foreach (@webPath) { | ||||
274 | 84 | 467µs | $subWeb .= '/' if $subWeb; | ||
275 | $subWeb .= $_; | ||||
276 | 21 | 6.72ms | $back = $this->_getBackend( $subWeb, $Foswiki::cfg{WebPrefsTopicName} ); # spent 6.72ms making 21 calls to Foswiki::Prefs::_getBackend, avg 320µs/call | ||
277 | 21 | 5.63ms | $stack->newLevel($back); # spent 5.63ms making 21 calls to Foswiki::Prefs::Stack::newLevel, avg 268µs/call | ||
278 | } | ||||
279 | 21 | 7.92ms | $back = $this->_getBackend( $web, $topic ); # spent 7.92ms making 21 calls to Foswiki::Prefs::_getBackend, avg 377µs/call | ||
280 | 21 | 1.36ms | $stack->newLevel($back); # spent 1.36ms making 21 calls to Foswiki::Prefs::Stack::newLevel, avg 65µs/call | ||
281 | 42 | 1.92ms | $stack->newLevel( Foswiki::Prefs::HASH->new() ); # spent 1.12ms making 21 calls to Foswiki::Prefs::Stack::newLevel, avg 54µs/call
# spent 801µs making 21 calls to Foswiki::Prefs::HASH::new, avg 38µs/call | ||
282 | |||||
283 | 563 | 1.98ms | while ( my ( $k, $v ) = each %{ $this->{internals} } ) { | ||
284 | 271 | 16.1ms | $stack->insert( 'Set', $k, $v ); # spent 16.1ms making 271 calls to Foswiki::Prefs::Stack::insert, avg 59µs/call | ||
285 | } | ||||
286 | |||||
287 | } | ||||
288 | |||||
289 | =begin TML | ||||
290 | |||||
291 | ---+++ popTopicContext() | ||||
292 | |||||
293 | Returns the context to the state it was in before the | ||||
294 | =pushTopicContext= was last called. | ||||
295 | |||||
296 | =cut | ||||
297 | |||||
298 | # spent 34.2ms (4.10+30.1) within Foswiki::Prefs::popTopicContext which was called 20 times, avg 1.71ms/call:
# 20 times (4.10ms+30.1ms) by Foswiki::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm:343] at line 341 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm, avg 1.71ms/call | ||||
299 | 160 | 2.96ms | my $this = shift; | ||
300 | my $stack = $this->{main}; | ||||
301 | 20 | 40µs | my $context = pop( @{ $this->{contexts} } ); | ||
302 | my $level = $context->{level}; | ||||
303 | 540 | 923µs | while ( my ( $k, $v ) = each %{ $context->{internals} } ) { | ||
304 | $this->{internals}{$k} = $v; | ||||
305 | } | ||||
306 | 20 | 29.3ms | $stack->restore($level); # spent 29.3ms making 20 calls to Foswiki::Prefs::Stack::restore, avg 1.47ms/call | ||
307 | 20 | 40µs | splice @{ $this->{prefix} }, $level + 1 if @{ $this->{prefix} } > $level; | ||
308 | return ( | ||||
309 | 120 | 738µs | $stack->backAtLevel(-3)->topicObject->web(), # spent 244µs making 40 calls to Foswiki::Prefs::TopicRAM::topicObject, avg 6µs/call
# spent 194µs making 40 calls to Foswiki::Prefs::Stack::backAtLevel, avg 5µs/call
# spent 155µs making 20 calls to Foswiki::Meta::web, avg 8µs/call
# spent 145µs making 20 calls to Foswiki::Meta::topic, avg 7µs/call | ||
310 | $stack->backAtLevel(-2)->topicObject->topic() | ||||
311 | ); | ||||
312 | } | ||||
313 | |||||
314 | =begin TML | ||||
315 | |||||
316 | ---++ ObjectMethod setPluginPreferences( $web, $plugin ) | ||||
317 | |||||
318 | Reads preferences from the given plugin topic and injects them into | ||||
319 | the plugin preferences cache. Preferences cannot be finalised in | ||||
320 | plugin topics. | ||||
321 | |||||
322 | =cut | ||||
323 | |||||
324 | sub setPluginPreferences { | ||||
325 | my ( $this, $web, $plugin ) = @_; | ||||
326 | my $back = $this->_getBackend( $web, $plugin ); | ||||
327 | my $prefix = uc($plugin) . '_'; | ||||
328 | my $stack = $this->{main}; | ||||
329 | $stack->newLevel( $back, $prefix ); | ||||
330 | $this->{prefix}->[ $stack->size() - 1 ] = $prefix; | ||||
331 | } | ||||
332 | |||||
333 | =begin TML | ||||
334 | |||||
335 | ---++ ObjectMethod setUserPreferences( $wikiname ) | ||||
336 | |||||
337 | Reads preferences from the given user topic and pushes them to the preferences | ||||
338 | stack. | ||||
339 | |||||
340 | =cut | ||||
341 | |||||
342 | # spent 7.72ms (23µs+7.70) within Foswiki::Prefs::setUserPreferences which was called:
# once (23µs+7.70ms) by Foswiki::new at line 1888 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm | ||||
343 | 3 | 25µs | my ( $this, $wn ) = @_; | ||
344 | 1 | 7.64ms | my $back = $this->_getBackend( $Foswiki::cfg{UsersWebName}, $wn ); # spent 7.64ms making 1 call to Foswiki::Prefs::_getBackend | ||
345 | 1 | 52µs | $this->{main}->newLevel($back); # spent 52µs making 1 call to Foswiki::Prefs::Stack::newLevel | ||
346 | } | ||||
347 | |||||
348 | =begin TML | ||||
349 | |||||
350 | ---++ ObjectMethod loadDefaultPreferences() | ||||
351 | |||||
352 | Add default preferences to this preferences stack. | ||||
353 | |||||
354 | =cut | ||||
355 | |||||
356 | # spent 282ms (67µs+282) within Foswiki::Prefs::loadDefaultPreferences which was called:
# once (67µs+282ms) by Foswiki::new at line 1858 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm | ||||
357 | 3 | 74µs | my $this = shift; | ||
358 | 1 | 280ms | my $back = $this->_getBackend( $Foswiki::cfg{SystemWebName}, # spent 280ms making 1 call to Foswiki::Prefs::_getBackend | ||
359 | $Foswiki::cfg{SitePrefsTopicName} ); | ||||
360 | 1 | 1.41ms | $this->{main}->newLevel($back); # spent 1.41ms making 1 call to Foswiki::Prefs::Stack::newLevel | ||
361 | } | ||||
362 | |||||
363 | =begin TML | ||||
364 | |||||
365 | ---++ ObjectMethod loadSitePreferences() | ||||
366 | Add local site preferences to this preferences stack. | ||||
367 | |||||
368 | =cut | ||||
369 | |||||
370 | # spent 6.00ms (45µs+5.96) within Foswiki::Prefs::loadSitePreferences which was called:
# once (45µs+5.96ms) by Foswiki::new at line 1882 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm | ||||
371 | 2 | 14µs | my $this = shift; | ||
372 | 3 | 29µs | if ( $Foswiki::cfg{LocalSitePreferences} ) { | ||
373 | 1 | 90µs | my ( $web, $topic ) = # spent 90µs making 1 call to Foswiki::normalizeWebTopicName | ||
374 | $this->{session} | ||||
375 | ->normalizeWebTopicName( undef, $Foswiki::cfg{LocalSitePreferences} ); | ||||
376 | 1 | 5.37ms | my $back = $this->_getBackend( $web, $topic ); # spent 5.37ms making 1 call to Foswiki::Prefs::_getBackend | ||
377 | 1 | 498µs | $this->{main}->newLevel($back); # spent 498µs making 1 call to Foswiki::Prefs::Stack::newLevel | ||
378 | } | ||||
379 | } | ||||
380 | |||||
381 | =begin TML | ||||
382 | |||||
383 | ---++ ObjectMethod setSessionPreferences( %values ) | ||||
384 | |||||
385 | Set the preference values in the parameters in the SESSION stack. | ||||
386 | |||||
387 | =cut | ||||
388 | |||||
389 | # spent 6.05ms (1.57+4.48) within Foswiki::Prefs::setSessionPreferences which was called 21 times, avg 288µs/call:
# 20 times (1.50ms+4.30ms) by Foswiki::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm:326] at line 223 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm, avg 290µs/call
# once (73µs+180µs) by Foswiki::UI::View::view at line 340 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/UI/View.pm | ||||
390 | 105 | 773µs | my ( $this, %values ) = @_; | ||
391 | my $stack = $this->{main}; | ||||
392 | my $num = 0; | ||||
393 | 108 | 714µs | while ( my ( $k, $v ) = each %values ) { | ||
394 | 54 | 474µs | next if $stack->finalized($k); # spent 474µs making 54 calls to Foswiki::Prefs::Stack::finalized, avg 9µs/call | ||
395 | 54 | 4.01ms | $num += $stack->insert( 'Set', $k, $v ); # spent 4.01ms making 54 calls to Foswiki::Prefs::Stack::insert, avg 74µs/call | ||
396 | } | ||||
397 | |||||
398 | return $num; | ||||
399 | } | ||||
400 | |||||
401 | =begin TML | ||||
402 | |||||
403 | ---++ ObjectMethod setInternalPreferences( %values ) | ||||
404 | |||||
405 | Designed specifically for imposing the value of preferences on a short-term | ||||
406 | basis in the code, internal preferences override all other definitions of | ||||
407 | the same tag. This function should be used with great care. | ||||
408 | |||||
409 | For those who are used to the old code, internal preferences replace the old | ||||
410 | SESSION_TAGS field from the Foswiki object. | ||||
411 | |||||
412 | =cut | ||||
413 | |||||
414 | # spent 144ms within Foswiki::Prefs::setInternalPreferences which was called 6951 times, avg 21µs/call:
# 2321 times (47.5ms+0s) by Foswiki::innerExpandMacros at line 2743 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 20µs/call
# 2321 times (47.1ms+0s) by Foswiki::innerExpandMacros at line 2721 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 20µs/call
# 1131 times (25.0ms+0s) by Foswiki::expandMacros at line 3243 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 22µs/call
# 1131 times (22.8ms+0s) by Foswiki::expandMacros at line 3260 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 20µs/call
# 20 times (630µs+0s) by Foswiki::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm:326] at line 226 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm, avg 31µs/call
# 20 times (438µs+0s) by Foswiki::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm:343] at line 332 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm, avg 22µs/call
# 5 times (75µs+0s) by Foswiki::LoginManager::loadSession at line 465 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/LoginManager.pm, avg 15µs/call
# once (48µs+0s) by Foswiki::new at line 1871 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm
# once (29µs+0s) by Foswiki::LoginManager::loadSession at line 457 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/LoginManager.pm | ||||
415 | 13902 | 127ms | my ( $this, %values ) = @_; | ||
416 | |||||
417 | 13899 | 25.8ms | while ( my ( $k, $v ) = each %values ) { | ||
418 | $this->{internals}{$k} = $v; | ||||
419 | } | ||||
420 | } | ||||
421 | |||||
422 | =begin TML | ||||
423 | |||||
424 | ---++ ObjectMethod getPreference( $key ) -> $value | ||||
425 | * =$key - key to look up | ||||
426 | |||||
427 | Returns the finalised preference value. | ||||
428 | |||||
429 | =cut | ||||
430 | |||||
431 | # spent 102ms (79.2+22.3) within Foswiki::Prefs::getPreference which was called 7613 times, avg 13µs/call:
# 2321 times (18.2ms+393µs) by Foswiki::innerExpandMacros at line 2714 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 8µs/call
# 2321 times (17.7ms+340µs) by Foswiki::innerExpandMacros at line 2715 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 8µs/call
# 1131 times (9.58ms+0s) by Foswiki::expandMacros at line 3241 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 8µs/call
# 1131 times (8.67ms+0s) by Foswiki::expandMacros at line 3242 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 8µs/call
# 562 times (19.1ms+15.8ms) by Foswiki::_expandMacroOnTopicRendering at line 3034 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 62µs/call
# 22 times (959µs+936µs) by Foswiki::Func::getPreferencesValue at line 729 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Func.pm, avg 86µs/call
# 20 times (1.36ms+1.72ms) by Foswiki::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm:326] at line 290 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm, avg 154µs/call
# 20 times (329µs+0s) by Foswiki::INCLUDE at line 214 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm, avg 16µs/call
# 20 times (160µs+0s) by Foswiki::INCLUDE at line 215 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm, avg 8µs/call
# 18 times (1.03ms+1.14ms) by Foswiki::INCLUDE at line 130 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/INCLUDE.pm, avg 120µs/call
# 10 times (392µs+326µs) by Foswiki::If::OP_defined::evaluate at line 39 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/If/OP_defined.pm, avg 72µs/call
# 7 times (452µs+489µs) by Foswiki::getSkin at line 1367 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 134µs/call
# 7 times (284µs+227µs) by Foswiki::getSkin at line 1356 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm, avg 73µs/call
# 5 times (313µs+345µs) by Foswiki::Render::getRenderedVersion at line 1411 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Render.pm, avg 132µs/call
# 4 times (156µs+118µs) by Foswiki::WIKIUSERNAME at line 12 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/WIKIUSERNAME.pm, avg 69µs/call
# 4 times (35µs+0s) by Foswiki::LoginManager::_LOGOUTURL at line 1063 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/LoginManager.pm, avg 9µs/call
# 3 times (99µs+75µs) by Foswiki::WIKINAME at line 12 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/WIKINAME.pm, avg 58µs/call
# once (86µs+102µs) by Foswiki::UI::View::view at line 218 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/UI/View.pm
# once (63µs+81µs) by Foswiki::Func::getPluginPreferencesValue at line 753 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Func.pm
# once (66µs+74µs) by Foswiki::Render::_linkToolTipInfo at line 467 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Render.pm
# once (64µs+67µs) by Foswiki::writeCompletePage at line 770 of /usr/local/src/github.com/foswiki/core/lib/Foswiki.pm
# once (59µs+64µs) by Foswiki::Render::_newLinkFormat at line 122 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Render.pm
# once (54µs+32µs) by Foswiki::Plugins::enable at line 244 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugins.pm
# once (34µs+26µs) by Foswiki::USERNAME at line 13 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Macros/USERNAME.pm | ||||
432 | 18316 | 43.3ms | my ( $this, $key ) = @_; | ||
433 | 6995 | 39.9ms | if ( defined $this->{internals}{$key} ) { | ||
434 | return $this->{internals}{$key}; | ||||
435 | } | ||||
436 | |||||
437 | my $value; | ||||
438 | my $stack = $this->{main}; | ||||
439 | 1652 | 13.0ms | $value = $stack->backAtLevel(-2)->getLocal($key) # spent 7.26ms making 618 calls to Foswiki::Prefs::Stack::finalizedBefore, avg 12µs/call
# spent 3.23ms making 517 calls to Foswiki::Prefs::TopicRAM::getLocal, avg 6µs/call
# spent 2.51ms making 517 calls to Foswiki::Prefs::Stack::backAtLevel, avg 5µs/call | ||
440 | unless $stack->finalizedBefore( $key, -2 ); | ||||
441 | 668 | 3.31ms | 618 | 3.15ms | if ( !defined $value && $stack->prefIsDefined($key) ) { # spent 3.15ms making 618 calls to Foswiki::Prefs::Stack::prefIsDefined, avg 5µs/call |
442 | 167 | 4.07ms | my $defLevel = $stack->getDefinitionLevel($key); # spent 4.07ms making 167 calls to Foswiki::Prefs::Stack::getDefinitionLevel, avg 24µs/call | ||
443 | my $prefix = $this->{prefix}->[$defLevel]; | ||||
444 | $key =~ s/^\Q$prefix\E// if $prefix; | ||||
445 | 334 | 2.10ms | $value = $stack->backAtLevel($defLevel)->get($key); # spent 877µs making 117 calls to Foswiki::Prefs::TopicRAM::get, avg 7µs/call
# spent 842µs making 167 calls to Foswiki::Prefs::Stack::backAtLevel, avg 5µs/call
# spent 382µs making 50 calls to Foswiki::Prefs::HASH::get, avg 8µs/call | ||
446 | } | ||||
447 | return $value; | ||||
448 | } | ||||
449 | |||||
450 | =begin TML | ||||
451 | |||||
452 | ---++ ObjectMethod stringify([$key]) -> $text | ||||
453 | |||||
454 | Generate TML-formatted information about the key (all keys if $key is undef) | ||||
455 | |||||
456 | =cut | ||||
457 | |||||
458 | sub stringify { | ||||
459 | my ( $this, $key ) = @_; | ||||
460 | |||||
461 | my $stack = $this->{main}; | ||||
462 | my @keys = defined $key ? ($key) : sort $stack->prefs; | ||||
463 | my @list; | ||||
464 | foreach my $k (@keys) { | ||||
465 | my $val = Foswiki::entityEncode( $this->getPreference($k) || '' ); | ||||
466 | push( @list, ' * Set ' . "$k = \"$val\"" ); | ||||
467 | next unless exists $stack->{'map'}{$k}; | ||||
468 | my $defLevel = $stack->getDefinitionLevel($k); | ||||
469 | if ( $stack->backAtLevel($defLevel)->can('topicObject') ) { | ||||
470 | my $topicObject = $stack->backAtLevel($defLevel)->topicObject(); | ||||
471 | push( @list, | ||||
472 | " * $k was " | ||||
473 | . ( $stack->finalized($k) ? '*finalised*' : 'defined' ) | ||||
474 | . ' in <nop>' | ||||
475 | . $topicObject->web() . '.' | ||||
476 | . $topicObject->topic() ); | ||||
477 | } | ||||
478 | } | ||||
479 | |||||
480 | @keys = | ||||
481 | defined $key ? ($key) : ( sort $stack->backAtLevel(-2)->localPrefs ); | ||||
482 | foreach my $k (@keys) { | ||||
483 | next | ||||
484 | unless defined $stack->backAtLevel(-2)->getLocal($k) | ||||
485 | && !$stack->finalizedBefore( $k, -2 ); | ||||
486 | my $val = | ||||
487 | Foswiki::entityEncode( $stack->backAtLevel(-2)->getLocal($k) ); | ||||
488 | push( @list, ' * Local ' . "$k = \"$val\"" ); | ||||
489 | } | ||||
490 | |||||
491 | return join( "\n", @list ) . "\n"; | ||||
492 | } | ||||
493 | |||||
494 | 1 | 5µs | 1; | ||
495 | __END__ |