← Index
NYTProf Performance Profile   « line view »
For rbm/rbm
  Run on Wed Feb 12 03:38:15 2020
Reported on Wed Feb 12 04:56:35 2020

Filename/usr/lib/x86_64-linux-gnu/perl5/5.28/Template/Provider.pm
StatementsExecuted 24279473 statements in 45.9s
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
3831611117.0s17.7sTemplate::Provider::::_initTemplate::Provider::_init
3841742113.4s405sTemplate::Provider::::_compileTemplate::Provider::_compile
384174117.53s418sTemplate::Provider::::fetchTemplate::Provider::fetch
384189215.21s5.46sTemplate::Provider::::_loadTemplate::Provider::_load
383161112.02s2.02sTemplate::Provider::::DESTROYTemplate::Provider::DESTROY
38417421700ms700msTemplate::Provider::::CORE:regcompTemplate::Provider::CORE:regcomp (opcode)
30542166.2ms66.2msTemplate::Provider::::CORE:statTemplate::Provider::CORE:stat (opcode)
10281153.5ms12.8sTemplate::Provider::::_fetchTemplate::Provider::_fetch
10131140.7ms92.6msTemplate::Provider::::_storeTemplate::Provider::_store
10131139.4ms39.4msTemplate::Provider::::CORE:openTemplate::Provider::CORE:open (opcode)
10131136.1ms112msTemplate::Provider::::_template_contentTemplate::Provider::_template_content
10131134.7ms101msTemplate::Provider::::_decode_unicodeTemplate::Provider::_decode_unicode
10131131.1ms12.9sTemplate::Provider::::_fetch_pathTemplate::Provider::_fetch_path
10131118.9ms18.9msTemplate::Provider::::CORE:readlineTemplate::Provider::CORE:readline (opcode)
20412118.8ms82.4msTemplate::Provider::::_template_modifiedTemplate::Provider::_template_modified
10131118.5ms111msTemplate::Provider::::storeTemplate::Provider::store
10131114.4ms14.4msTemplate::Provider::::pathsTemplate::Provider::paths
10131110.9ms51.8msTemplate::Provider::::_modifiedTemplate::Provider::_modified
1013119.20ms9.20msTemplate::Provider::::CORE:closeTemplate::Provider::CORE:close (opcode)
2041219.00ms9.00msTemplate::Provider::::_compiled_filenameTemplate::Provider::_compiled_filename
1028117.24ms13.7msTemplate::Provider::::_compiled_is_currentTemplate::Provider::_compiled_is_current
1013113.60ms3.60msTemplate::Provider::::CORE:ftdirTemplate::Provider::CORE:ftdir (opcode)
1112.00ms2.13msTemplate::Provider::::BEGIN@46Template::Provider::BEGIN@46
1013111.94ms1.94msTemplate::Provider::::CORE:binmodeTemplate::Provider::CORE:binmode (opcode)
1013111.30ms1.30msTemplate::Provider::::CORE:matchTemplate::Provider::CORE:match (opcode)
11118µs22µsTemplate::Provider::::BEGIN@1092Template::Provider::BEGIN@1092
11116µs18µsTemplate::Provider::::BEGIN@41Template::Provider::BEGIN@41
11114µs14µsTemplate::Provider::::BEGIN@48Template::Provider::BEGIN@48
1119µs10µsTemplate::Provider::::BEGIN@44Template::Provider::BEGIN@44
1118µs53µsTemplate::Provider::::BEGIN@47Template::Provider::BEGIN@47
1117µs82µsTemplate::Provider::::BEGIN@50Template::Provider::BEGIN@50
1116µs26µsTemplate::Provider::::BEGIN@42Template::Provider::BEGIN@42
1116µs30µsTemplate::Provider::::BEGIN@51Template::Provider::BEGIN@51
1115µs57µsTemplate::Provider::::BEGIN@43Template::Provider::BEGIN@43
1115µs18µsTemplate::Provider::::BEGIN@45Template::Provider::BEGIN@45
1115µs28µsTemplate::Provider::::BEGIN@52Template::Provider::BEGIN@52
1115µs25µsTemplate::Provider::::BEGIN@55Template::Provider::BEGIN@55
1114µs27µsTemplate::Provider::::BEGIN@53Template::Provider::BEGIN@53
1114µs24µsTemplate::Provider::::BEGIN@54Template::Provider::BEGIN@54
1113µs3µsTemplate::Provider::::CORE:qrTemplate::Provider::CORE:qr (opcode)
1113µs3µsTemplate::Provider::::BEGIN@87Template::Provider::BEGIN@87
3312µs2µsTemplate::Provider::::__ANON__Template::Provider::__ANON__ (xsub)
0000s0sTemplate::Provider::::_dumpTemplate::Provider::_dump
0000s0sTemplate::Provider::::_dump_cacheTemplate::Provider::_dump_cache
0000s0sTemplate::Provider::::_load_compiledTemplate::Provider::_load_compiled
0000s0sTemplate::Provider::::_refreshTemplate::Provider::_refresh
0000s0sTemplate::Provider::::include_pathTemplate::Provider::include_path
0000s0sTemplate::Provider::::loadTemplate::Provider::load
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1#============================================================= -*-Perl-*-
2#
3# Template::Provider
4#
5# DESCRIPTION
6# This module implements a class which handles the loading, compiling
7# and caching of templates. Multiple Template::Provider objects can
8# be stacked and queried in turn to effect a Chain-of-Command between
9# them. A provider will attempt to return the requested template,
10# an error (STATUS_ERROR) or decline to provide the template
11# (STATUS_DECLINE), allowing subsequent providers to attempt to
12# deliver it. See 'Design Patterns' for further details.
13#
14# AUTHORS
15# Andy Wardley <abw@wardley.org>
16#
17# Refactored by Bill Moseley for v2.19 to add negative caching (i.e.
18# tracking templates that are NOTFOUND so that we can decline quickly)
19# and to provide better support for subclassing the provider.
20#
21# COPYRIGHT
22# Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
23#
24# This module is free software; you can redistribute it and/or
25# modify it under the same terms as Perl itself.
26#
27# WARNING:
28# This code is ugly and contorted and is being totally re-written for TT3.
29# In particular, we'll be throwing errors rather than messing around
30# returning (value, status) pairs. With the benefit of hindsight, that
31# was a really bad design decision on my part. I deserve to be knocked
32# to the ground and kicked around a bit by hoards of angry TT developers
33# for that one. Bill's refactoring has made the module easier to subclass,
34# (so you can ease off the kicking now), but it really needs to be totally
35# redesigned and rebuilt from the ground up along with the bits of TT that
36# use it. -- abw 2007/04/27
37#============================================================================
38
39package Template::Provider;
40
41221µs221µs
# spent 18µs (16+3) within Template::Provider::BEGIN@41 which was called: # once (16µs+3µs) by Template::BEGIN@29 at line 41
use strict;
# spent 18µs making 1 call to Template::Provider::BEGIN@41 # spent 3µs making 1 call to strict::import
42219µs247µs
# spent 26µs (6+20) within Template::Provider::BEGIN@42 which was called: # once (6µs+20µs) by Template::BEGIN@29 at line 42
use warnings;
# spent 26µs making 1 call to Template::Provider::BEGIN@42 # spent 20µs making 1 call to warnings::import
43223µs2108µs
# spent 57µs (5+52) within Template::Provider::BEGIN@43 which was called: # once (5µs+52µs) by Template::BEGIN@29 at line 43
use base 'Template::Base';
# spent 57µs making 1 call to Template::Provider::BEGIN@43 # spent 52µs making 1 call to base::import
44222µs210µs
# spent 10µs (9+500ns) within Template::Provider::BEGIN@44 which was called: # once (9µs+500ns) by Template::BEGIN@29 at line 44
use Template::Config;
# spent 10µs making 1 call to Template::Provider::BEGIN@44 # spent 500ns making 1 call to Template::Provider::__ANON__
45217µs231µs
# spent 18µs (5+13) within Template::Provider::BEGIN@45 which was called: # once (5µs+13µs) by Template::BEGIN@29 at line 45
use Template::Constants;
# spent 18µs making 1 call to Template::Provider::BEGIN@45 # spent 13µs making 1 call to Exporter::import
462792µs22.13ms
# spent 2.13ms (2.00+122µs) within Template::Provider::BEGIN@46 which was called: # once (2.00ms+122µs) by Template::BEGIN@29 at line 46
use Template::Document;
# spent 2.13ms making 1 call to Template::Provider::BEGIN@46 # spent 900ns making 1 call to Template::Provider::__ANON__
47224µs297µs
# spent 53µs (8+45) within Template::Provider::BEGIN@47 which was called: # once (8µs+45µs) by Template::BEGIN@29 at line 47
use File::Basename;
# spent 53µs making 1 call to Template::Provider::BEGIN@47 # spent 45µs making 1 call to Exporter::import
48231µs215µs
# spent 14µs (14+400ns) within Template::Provider::BEGIN@48 which was called: # once (14µs+400ns) by Template::BEGIN@29 at line 48
use File::Spec;
# spent 14µs making 1 call to Template::Provider::BEGIN@48 # spent 400ns making 1 call to Template::Provider::__ANON__
49
50227µs2157µs
# spent 82µs (7+75) within Template::Provider::BEGIN@50 which was called: # once (7µs+75µs) by Template::BEGIN@29 at line 50
use constant PREV => 0;
# spent 82µs making 1 call to Template::Provider::BEGIN@50 # spent 75µs making 1 call to constant::import
512137µs254µs
# spent 30µs (6+24) within Template::Provider::BEGIN@51 which was called: # once (6µs+24µs) by Template::BEGIN@29 at line 51
use constant NAME => 1; # template name -- indexed by this name in LOOKUP
# spent 30µs making 1 call to Template::Provider::BEGIN@51 # spent 24µs making 1 call to constant::import
52221µs252µs
# spent 28µs (5+24) within Template::Provider::BEGIN@52 which was called: # once (5µs+24µs) by Template::BEGIN@29 at line 52
use constant DATA => 2; # Compiled template
# spent 28µs making 1 call to Template::Provider::BEGIN@52 # spent 24µs making 1 call to constant::import
53220µs249µs
# spent 27µs (4+22) within Template::Provider::BEGIN@53 which was called: # once (4µs+22µs) by Template::BEGIN@29 at line 53
use constant LOAD => 3; # mtime of template
# spent 27µs making 1 call to Template::Provider::BEGIN@53 # spent 22µs making 1 call to constant::import
54221µs244µs
# spent 24µs (4+20) within Template::Provider::BEGIN@54 which was called: # once (4µs+20µs) by Template::BEGIN@29 at line 54
use constant NEXT => 4; # link to next item in cache linked list
# spent 24µs making 1 call to Template::Provider::BEGIN@54 # spent 20µs making 1 call to constant::import
552160µs246µs
# spent 25µs (5+21) within Template::Provider::BEGIN@55 which was called: # once (5µs+21µs) by Template::BEGIN@29 at line 55
use constant STAT => 5; # Time last stat()ed
# spent 25µs making 1 call to Template::Provider::BEGIN@55 # spent 21µs making 1 call to constant::import
56
571400nsour $VERSION = 2.94;
581400nsour $DEBUG = 0 unless defined $DEBUG;
591300nsour $ERROR = '';
60
61# name of document class
621400nsour $DOCUMENT = 'Template::Document' unless defined $DOCUMENT;
63
64# maximum time between performing stat() on file to check staleness
651200nsour $STAT_TTL = 1 unless defined $STAT_TTL;
66
67# maximum number of directories in an INCLUDE_PATH, to prevent runaways
681100nsour $MAX_DIRS = 64 unless defined $MAX_DIRS;
69
70# UNICODE is supported in versions of Perl from 5.007 onwards
7111µsour $UNICODE = $] > 5.007 ? 1 : 0;
72
7312µsmy $boms = [
74 'UTF-8' => "\x{ef}\x{bb}\x{bf}",
75 'UTF-32BE' => "\x{0}\x{0}\x{fe}\x{ff}",
76 'UTF-32LE' => "\x{ff}\x{fe}\x{0}\x{0}",
77 'UTF-16BE' => "\x{fe}\x{ff}",
78 'UTF-16LE' => "\x{ff}\x{fe}",
79];
80
81# regex to match relative paths
8219µs13µsour $RELATIVE_PATH = qr[(?:^|/)\.+/];
# spent 3µs making 1 call to Template::Provider::CORE:qr
83
84
85# hack so that 'use bytes' will compile on versions of Perl earlier than
86# 5.6, even though we never call _decode_unicode() on those systems
87
# spent 3µs within Template::Provider::BEGIN@87 which was called: # once (3µs+0s) by Template::BEGIN@29 at line 92
BEGIN {
8814µs if ($] < 5.006) {
89 package bytes;
90 $INC{'bytes.pm'} = 1;
91 }
9214.78ms13µs}
# spent 3µs making 1 call to Template::Provider::BEGIN@87
93
94
95#========================================================================
96# -- PUBLIC METHODS --
97#========================================================================
98
99#------------------------------------------------------------------------
100# fetch($name)
101#
102# Returns a compiled template for the name specified by parameter.
103# The template is returned from the internal cache if it exists, or
104# loaded and then subsequently cached. The ABSOLUTE and RELATIVE
105# configuration flags determine if absolute (e.g. '/something...')
106# and/or relative (e.g. './something') paths should be honoured. The
107# INCLUDE_PATH is otherwise used to find the named file. $name may
108# also be a reference to a text string containing the template text,
109# or a file handle from which the content is read. The compiled
110# template is not cached in these latter cases given that there is no
111# filename to cache under. A subsequent call to store($name,
112# $compiled) can be made to cache the compiled template for future
113# fetch() calls, if necessary.
114#
115# Returns a compiled template or (undef, STATUS_DECLINED) if the
116# template could not be found. On error (e.g. the file was found
117# but couldn't be read or parsed), the pair ($error, STATUS_ERROR)
118# is returned. The TOLERANT configuration option can be set to
119# downgrade any errors to STATUS_DECLINE.
120#------------------------------------------------------------------------
121
122
# spent 418s (7.53+411) within Template::Provider::fetch which was called 384174 times, avg 1.09ms/call: # 384174 times (7.53s+411s) by Template::Context::template at line 140 of Template/Context.pm, avg 1.09ms/call
sub fetch {
123384174225ms my ($self, $name) = @_;
12438417477.7ms my ($data, $error);
125
126
127384174397ms303913.2ms if (ref $name) {
# spent 11.5ms making 1013 calls to File::Spec::Unix::file_name_is_absolute, avg 11µs/call # spent 1.30ms making 1013 calls to Template::Provider::CORE:match, avg 1µs/call # spent 445µs making 1013 calls to Template::Provider::CORE:regcomp, avg 440ns/call
128 # $name can be a reference to a scalar, GLOB or file handle
1293831611.47s3831615.16s ($data, $error) = $self->_load($name);
# spent 5.16s making 383161 calls to Template::Provider::_load, avg 13µs/call
1303831611.39s383161393s ($data, $error) = $self->_compile($data)
# spent 393s making 383161 calls to Template::Provider::_compile, avg 1.02ms/call
131 unless $error;
132 $data = $data->{ data }
133383161760ms unless $error;
134 }
135 elsif (File::Spec->file_name_is_absolute($name)) {
136 # absolute paths (starting '/') allowed if ABSOLUTE set
137 ($data, $error) = $self->{ ABSOLUTE }
138 ? $self->_fetch($name)
139 : $self->{ TOLERANT }
140 ? (undef, Template::Constants::STATUS_DECLINED)
141 : ("$name: absolute paths are not allowed (set ABSOLUTE option)",
142 Template::Constants::STATUS_ERROR);
143 }
144 elsif ($name =~ m/$RELATIVE_PATH/o) {
145 # anything starting "./" is relative to cwd, allowed if RELATIVE set
146 ($data, $error) = $self->{ RELATIVE }
147 ? $self->_fetch($name)
148 : $self->{ TOLERANT }
149 ? (undef, Template::Constants::STATUS_DECLINED)
150 : ("$name: relative paths are not allowed (set RELATIVE option)",
151 Template::Constants::STATUS_ERROR);
152 }
153 else {
154 # otherwise, it's a file name relative to INCLUDE_PATH
155 ($data, $error) = $self->{ INCLUDE_PATH }
15610135.24ms101312.9s ? $self->_fetch_path($name)
# spent 12.9s making 1013 calls to Template::Provider::_fetch_path, avg 12.7ms/call
157 : (undef, Template::Constants::STATUS_DECLINED);
158 }
159
160# $self->_dump_cache()
161# if $DEBUG > 1;
162
1633841741.87s return ($data, $error);
164}
165
166
167#------------------------------------------------------------------------
168# store($name, $data)
169#
170# Store a compiled template ($data) in the cached as $name.
171# Returns compiled template
172#------------------------------------------------------------------------
173
174
# spent 111ms (18.5+92.6) within Template::Provider::store which was called 1013 times, avg 110µs/call: # 1013 times (18.5ms+92.6ms) by Template::Provider::_fetch at line 490, avg 110µs/call
sub store {
17510131.51ms my ($self, $name, $data) = @_;
176101319.3ms101392.6ms $self->_store($name, {
# spent 92.6ms making 1013 calls to Template::Provider::_store, avg 91µs/call
177 data => $data,
178 load => 0,
179 });
180}
181
182
183#------------------------------------------------------------------------
184# load($name)
185#
186# Load a template without parsing/compiling it, suitable for use with
187# the INSERT directive. There's some duplication with fetch() and at
188# some point this could be reworked to integrate them a little closer.
189#------------------------------------------------------------------------
190
191sub load {
192 my ($self, $name) = @_;
193 my ($data, $error);
194 my $path = $name;
195
196 if (File::Spec->file_name_is_absolute($name)) {
197 # absolute paths (starting '/') allowed if ABSOLUTE set
198 $error = "$name: absolute paths are not allowed (set ABSOLUTE option)"
199 unless $self->{ ABSOLUTE };
200 }
201 elsif ($name =~ m[$RELATIVE_PATH]o) {
202 # anything starting "./" is relative to cwd, allowed if RELATIVE set
203 $error = "$name: relative paths are not allowed (set RELATIVE option)"
204 unless $self->{ RELATIVE };
205 }
206 else {
207 INCPATH: {
208 # otherwise, it's a file name relative to INCLUDE_PATH
209 my $paths = $self->paths()
210 || return ($self->error(), Template::Constants::STATUS_ERROR);
211
212 foreach my $dir (@$paths) {
213 $path = File::Spec->catfile($dir, $name);
214 last INCPATH
215 if $self->_template_modified($path);
216 }
217 undef $path; # not found
218 }
219 }
220
221 # Now fetch the content
222 ($data, $error) = $self->_template_content($path)
223 if defined $path && !$error;
224
225 if ($error) {
226 return $self->{ TOLERANT }
227 ? (undef, Template::Constants::STATUS_DECLINED)
228 : ($error, Template::Constants::STATUS_ERROR);
229 }
230 elsif (! defined $path) {
231 return (undef, Template::Constants::STATUS_DECLINED);
232 }
233 else {
234 return ($data, Template::Constants::STATUS_OK);
235 }
236}
237
- -
240#------------------------------------------------------------------------
241# include_path(\@newpath)
242#
243# Accessor method for the INCLUDE_PATH setting. If called with an
244# argument, this method will replace the existing INCLUDE_PATH with
245# the new value.
246#------------------------------------------------------------------------
247
248sub include_path {
249 my ($self, $path) = @_;
250 $self->{ INCLUDE_PATH } = $path if $path;
251 return $self->{ INCLUDE_PATH };
252}
253
254
255#------------------------------------------------------------------------
256# paths()
257#
258# Evaluates the INCLUDE_PATH list, ignoring any blank entries, and
259# calling and subroutine or object references to return dynamically
260# generated path lists. Returns a reference to a new list of paths
261# or undef on error.
262#------------------------------------------------------------------------
263
264
# spent 14.4ms within Template::Provider::paths which was called 1013 times, avg 14µs/call: # 1013 times (14.4ms+0s) by Template::Provider::_fetch_path at line 520, avg 14µs/call
sub paths {
2651013450µs my $self = shift;
26610132.67ms my @ipaths = @{ $self->{ INCLUDE_PATH } };
26710131.33ms my (@opaths, $dpaths, $dir);
2681013795µs my $count = $MAX_DIRS;
269
27010131.13ms while (@ipaths && --$count) {
2712026949µs $dir = shift @ipaths || next;
272
273 # $dir can be a sub or object ref which returns a reference
274 # to a dynamically generated list of search paths.
275
27620261.97ms if (ref $dir eq 'CODE') {
277 eval { $dpaths = &$dir() };
278 if ($@) {
279 chomp $@;
280 return $self->error($@);
281 }
282 unshift(@ipaths, @$dpaths);
283 next;
284 }
285 elsif (ref($dir) && UNIVERSAL::can($dir, 'paths')) {
286 $dpaths = $dir->paths()
287 || return $self->error($dir->error());
288 unshift(@ipaths, @$dpaths);
289 next;
290 }
291 else {
29220261.04ms push(@opaths, $dir);
293 }
294 }
2951013570µs return $self->error("INCLUDE_PATH exceeds $MAX_DIRS directories")
296 if @ipaths;
297
29810133.75ms return \@opaths;
299}
300
301
302#------------------------------------------------------------------------
303# DESTROY
304#
305# The provider cache is implemented as a doubly linked list which Perl
306# cannot free by itself due to the circular references between NEXT <=>
307# PREV items. This cleanup method walks the list deleting all the NEXT/PREV
308# references, allowing the proper cleanup to occur and memory to be
309# repooled.
310#------------------------------------------------------------------------
311
312
# spent 2.02s within Template::Provider::DESTROY which was called 383161 times, avg 5µs/call: # 383161 times (2.02s+0s) by RBM::process_template at line 663 of /root/tor-browser-build/rbm/lib/RBM.pm, avg 5µs/call
sub DESTROY {
313383161164ms my $self = shift;
314383161140ms my ($slot, $next);
315
316383161296ms $slot = $self->{ HEAD };
317383161218ms while ($slot) {
3181013615µs $next = $slot->[ NEXT ];
3191013584µs undef $slot->[ PREV ];
3201013100µs undef $slot->[ NEXT ];
3211013512µs $slot = $next;
322 }
323383161326ms undef $self->{ HEAD };
3243831612.06s undef $self->{ TAIL };
325}
326
- -
330#========================================================================
331# -- PRIVATE METHODS --
332#========================================================================
333
334#------------------------------------------------------------------------
335# _init()
336#
337# Initialise the cache.
338#------------------------------------------------------------------------
339
340
# spent 17.7s (17.0+700ms) within Template::Provider::_init which was called 383161 times, avg 46µs/call: # 383161 times (17.0s+700ms) by Template::Base::new at line 65 of Template/Base.pm, avg 46µs/call
sub _init {
341383161194ms my ($self, $params) = @_;
342383161496ms my $size = $params->{ CACHE_SIZE };
343383161421ms my $path = $params->{ INCLUDE_PATH } || '.';
344383161447ms my $cdir = $params->{ COMPILE_DIR } || '';
345383161378ms my $dlim = $params->{ DELIMITER };
346383161106ms my $debug;
347
348 # tweak delim to ignore C:/
3493831611.16s unless (defined $dlim) {
350 $dlim = ($^O eq 'MSWin32') ? ':(?!\\/)' : ':';
351 }
352
353 # coerce INCLUDE_PATH to an array ref, if not already so
3543831613.81s383161700ms $path = [ split(/$dlim/, $path) ]
# spent 700ms making 383161 calls to Template::Provider::CORE:regcomp, avg 2µs/call
355 unless ref $path eq 'ARRAY';
356
357 # don't allow a CACHE_SIZE 1 because it breaks things and the
358 # additional checking isn't worth it
359383161277ms $size = 2
360 if defined $size && ($size == 1 || $size < 0);
361
362383161576ms if (defined ($debug = $params->{ DEBUG })) {
363 $self->{ DEBUG } = $debug & ( Template::Constants::DEBUG_PROVIDER
364 | Template::Constants::DEBUG_FLAGS );
365 }
366 else {
367383161339ms $self->{ DEBUG } = $DEBUG;
368 }
369
370383161233ms if ($self->{ DEBUG }) {
371 local $" = ', ';
372 $self->debug("creating cache of ",
373 defined $size ? $size : 'unlimited',
374 " slots for [ @$path ]");
375 }
376
377 # create COMPILE_DIR and sub-directories representing each INCLUDE_PATH
378 # element in which to store compiled files
379383161160ms if ($cdir) {
380 require File::Path;
381 foreach my $dir (@$path) {
382 next if ref $dir;
383 my $wdir = $dir;
384 $wdir =~ s[:][]g if $^O eq 'MSWin32';
385 $wdir =~ /(.*)/; # untaint
386 $wdir = "$1"; # quotes work around bug in Strawberry Perl
387 $wdir = File::Spec->catfile($cdir, $wdir);
388 File::Path::mkpath($wdir) unless -d $wdir;
389 }
390 }
391
392383161548ms $self->{ LOOKUP } = { };
393383161667ms $self->{ NOTFOUND } = { }; # Tracks templates *not* found.
394383161606ms $self->{ SLOTS } = 0;
395383161284ms $self->{ SIZE } = $size;
396383161414ms $self->{ INCLUDE_PATH } = $path;
397383161272ms $self->{ DELIMITER } = $dlim;
398383161287ms $self->{ COMPILE_DIR } = $cdir;
399383161432ms $self->{ COMPILE_EXT } = $params->{ COMPILE_EXT } || '';
400383161402ms $self->{ ABSOLUTE } = $params->{ ABSOLUTE } || 0;
401383161855ms $self->{ RELATIVE } = $params->{ RELATIVE } || 0;
402383161441ms $self->{ TOLERANT } = $params->{ TOLERANT } || 0;
403383161561ms $self->{ DOCUMENT } = $params->{ DOCUMENT } || $DOCUMENT;
404383161355ms $self->{ PARSER } = $params->{ PARSER };
405383161391ms $self->{ DEFAULT } = $params->{ DEFAULT };
406383161261ms $self->{ ENCODING } = $params->{ ENCODING };
407# $self->{ PREFIX } = $params->{ PREFIX };
408383161628ms $self->{ STAT_TTL } = $params->{ STAT_TTL } || $STAT_TTL;
409383161258ms $self->{ PARAMS } = $params;
410
411 # look for user-provided UNICODE parameter or use default from package var
412 $self->{ UNICODE } = defined $params->{ UNICODE }
413383161432ms ? $params->{ UNICODE } : $UNICODE;
414
4153831611.94s return $self;
416}
417
418
419#------------------------------------------------------------------------
420# _fetch($name, $t_name)
421#
422# Fetch a file from cache or disk by specification of an absolute or
423# relative filename. No search of the INCLUDE_PATH is made. If the
424# file is found and loaded, it is compiled and cached.
425# Call with:
426# $name = path to search (possible prefixed by INCLUDE_PATH)
427# $t_name = template name
428#------------------------------------------------------------------------
429
430
# spent 12.8s (53.5ms+12.8) within Template::Provider::_fetch which was called 1028 times, avg 12.5ms/call: # 1028 times (53.5ms+12.8s) by Template::Provider::_fetch_path at line 529, avg 12.5ms/call
sub _fetch {
43110281.02ms my ($self, $name, $t_name) = @_;
43210281.52ms my $stat_ttl = $self->{ STAT_TTL };
433
43410281.26ms $self->debug("_fetch($name)") if $self->{ DEBUG };
435
436 # First see if the named template is in the memory cache
43710281.68ms if ((my $slot = $self->{ LOOKUP }->{ $name })) {
438 # Test if cache is fresh, and reload/compile if not.
439 my ($data, $error) = $self->_refresh($slot);
440
441 return $error
442 ? ( $data, $error ) # $data may contain error text
443 : $slot->[ DATA ]; # returned document object
444 }
445
446 # Otherwise, see if we already know the template is not found
44710281.51ms if (my $last_stat_time = $self->{ NOTFOUND }->{ $name }) {
448 my $expires_in = $last_stat_time + $stat_ttl - time;
449 if ($expires_in > 0) {
450 $self->debug(" file [$name] in negative cache. Expires in $expires_in seconds")
451 if $self->{ DEBUG };
452 return (undef, Template::Constants::STATUS_DECLINED);
453 }
454 else {
455 delete $self->{ NOTFOUND }->{ $name };
456 }
457 }
458
459 # Is there an up-to-date compiled version on disk?
46010284.20ms102813.7ms if ($self->_compiled_is_current($name)) {
# spent 13.7ms making 1028 calls to Template::Provider::_compiled_is_current, avg 13µs/call
461 # require() the compiled template.
462 my $compiled_template = $self->_load_compiled( $self->_compiled_filename($name) );
463
464 # Store and return the compiled template
465 return $self->store( $name, $compiled_template ) if $compiled_template;
466
467 # Problem loading compiled template:
468 # warn and continue to fetch source template
469 warn($self->error(), "\n");
470 }
471
472 # load template from source
47310283.43ms1028296ms my ($template, $error) = $self->_load($name, $t_name);
# spent 296ms making 1028 calls to Template::Provider::_load, avg 288µs/call
474
4751028458µs if ($error) {
476 # Template could not be fetched. Add to the negative/notfound cache.
47715157µs $self->{ NOTFOUND }->{ $name } = time;
4781562µs return ( $template, $error );
479 }
480
481 # compile template source
48210134.36ms202612.3s ($template, $error) = $self->_compile($template, $self->_compiled_filename($name) );
# spent 12.3s making 1013 calls to Template::Provider::_compile, avg 12.2ms/call # spent 2.49ms making 1013 calls to Template::Provider::_compiled_filename, avg 2µs/call
483
4841013689µs if ($error) {
485 # return any compile time error
486 return ($template, $error);
487 }
488 else {
489 # Store compiled template and return it
490101313.8ms1013111ms return $self->store($name, $template->{data}) ;
# spent 111ms making 1013 calls to Template::Provider::store, avg 110µs/call
491 }
492}
493
494
495#------------------------------------------------------------------------
496# _fetch_path($name)
497#
498# Fetch a file from cache or disk by specification of an absolute cache
499# name (e.g. 'header') or filename relative to one of the INCLUDE_PATH
500# directories. If the file isn't already cached and can be found and
501# loaded, it is compiled and cached under the full filename.
502#------------------------------------------------------------------------
503
504
# spent 12.9s (31.1ms+12.8) within Template::Provider::_fetch_path which was called 1013 times, avg 12.7ms/call: # 1013 times (31.1ms+12.8s) by Template::Provider::fetch at line 156, avg 12.7ms/call
sub _fetch_path {
5051013837µs my ($self, $name) = @_;
506
50710131.24ms $self->debug("_fetch_path($name)") if $self->{ DEBUG };
508
509 # the template may have been stored using a non-filename name
510 # so look for the plain name in the cache first
51110131.61ms if ((my $slot = $self->{ LOOKUP }->{ $name })) {
512 # cached entry exists, so refresh slot and extract data
513 my ($data, $error) = $self->_refresh($slot);
514
515 return $error
516 ? ($data, $error)
517 : ($slot->[ DATA ], $error );
518 }
519
52010135.83ms101314.4ms my $paths = $self->paths
# spent 14.4ms making 1013 calls to Template::Provider::paths, avg 14µs/call
521 || return ( $self->error, Template::Constants::STATUS_ERROR );
522
523 # search the INCLUDE_PATH for the file, in cache or on disk
52410131.40ms foreach my $dir (@$paths) {
525102835.0ms411238.5ms my $path = File::Spec->catfile($dir, $name);
# spent 29.2ms making 1028 calls to File::Spec::Unix::catfile, avg 28µs/call # spent 5.98ms making 1028 calls to File::Spec::Unix::catdir, avg 6µs/call # spent 3.26ms making 2056 calls to File::Spec::Unix::canonpath, avg 2µs/call
526
52710281.07ms $self->debug("searching path: $path\n") if $self->{ DEBUG };
528
52910284.75ms102812.8s my ($data, $error) = $self->_fetch( $path, $name );
# spent 12.8s making 1028 calls to Template::Provider::_fetch, avg 12.5ms/call
530
531 # Return if no error or if a serious error.
53210289.09ms return ( $data, $error )
533 if !$error || $error == Template::Constants::STATUS_ERROR;
534
535 }
536
537 # not found in INCLUDE_PATH, now try DEFAULT
538 return $self->_fetch_path( $self->{DEFAULT} )
539 if defined $self->{DEFAULT} && $name ne $self->{DEFAULT};
540
541 # We could not handle this template name
542 return (undef, Template::Constants::STATUS_DECLINED);
543}
544
545
# spent 9.00ms within Template::Provider::_compiled_filename which was called 2041 times, avg 4µs/call: # 1028 times (6.51ms+0s) by Template::Provider::_compiled_is_current at line 918, avg 6µs/call # 1013 times (2.49ms+0s) by Template::Provider::_fetch at line 482, avg 2µs/call
sub _compiled_filename {
54620411.20ms my ($self, $file) = @_;
54720413.58ms my ($compext, $compdir) = @$self{ qw( COMPILE_EXT COMPILE_DIR ) };
5482041490µs my ($path, $compiled);
549
550 return undef
55120416.24ms unless $compext || $compdir;
552
553 $path = $file;
554 $path =~ /^(.+)$/s or die "invalid filename: $path";
555 $path =~ s[:][]g if $^O eq 'MSWin32';
556
557 $compiled = "$path$compext";
558 $compiled = File::Spec->catfile($compdir, $compiled) if length $compdir;
559
560 return $compiled;
561}
562
563sub _load_compiled {
564 my ($self, $file) = @_;
565 my $compiled;
566
567 # load compiled template via require(); we zap any
568 # %INC entry to ensure it is reloaded (we don't
569 # want 1 returned by require() to say it's in memory)
570 delete $INC{ $file };
571 eval { $compiled = require $file; };
572 return $@
573 ? $self->error("compiled template $compiled: $@")
574 : $compiled;
575}
576
577#------------------------------------------------------------------------
578# _load($name, $alias)
579#
580# Load template text from a string ($name = scalar ref), GLOB or file
581# handle ($name = ref), or from an absolute filename ($name = scalar).
582# Returns a hash array containing the following items:
583# name filename or $alias, if provided, or 'input text', etc.
584# text template text
585# time modification time of file, or current time for handles/strings
586# load time file was loaded (now!)
587#
588# On error, returns ($error, STATUS_ERROR), or (undef, STATUS_DECLINED)
589# if TOLERANT is set.
590#------------------------------------------------------------------------
591
592
# spent 5.46s (5.21+254ms) within Template::Provider::_load which was called 384189 times, avg 14µs/call: # 383161 times (5.16s+0s) by Template::Provider::fetch at line 129, avg 13µs/call # 1028 times (41.6ms+254ms) by Template::Provider::_fetch at line 473, avg 288µs/call
sub _load {
593384189234ms my ($self, $name, $alias) = @_;
594384189172ms my ($data, $error);
595384189419ms my $tolerant = $self->{ TOLERANT };
596384189377ms my $now = time;
597
598384189283ms $alias = $name unless defined $alias or ref $name;
599
600 $self->debug("_load($name, ", defined $alias ? $alias : '<no alias>',
601384189266ms ')') if $self->{ DEBUG };
602
603 # SCALAR ref is the template text
6043841894.38s if (ref $name eq 'SCALAR') {
605 # $name can be a SCALAR reference to the input text...
606 return {
607 name => defined $alias ? $alias : 'input text',
608 path => defined $alias ? $alias : 'input text',
609 text => $$name,
610 time => $now,
611 load => 0,
612 };
613 }
614
615 # Otherwise, assume GLOB as a file handle
6161028583µs if (ref $name) {
617 local $/;
618 my $text = <$name>;
619 $text = $self->_decode_unicode($text) if $self->{ UNICODE };
620 return {
621 name => defined $alias ? $alias : 'input file handle',
622 path => defined $alias ? $alias : 'input file handle',
623 text => $text,
624 time => $now,
625 load => 0,
626 };
627 }
628
629 # Otherwise, it's the name of the template
63010283.02ms102841.4ms if ( $self->_template_modified( $name ) ) { # does template exist?
# spent 41.4ms making 1028 calls to Template::Provider::_template_modified, avg 40µs/call
63110134.62ms1013112ms my ($text, $error, $mtime ) = $self->_template_content( $name );
# spent 112ms making 1013 calls to Template::Provider::_template_content, avg 110µs/call
6321013789µs unless ( $error ) {
63310135.42ms1013101ms $text = $self->_decode_unicode($text) if $self->{ UNICODE };
# spent 101ms making 1013 calls to Template::Provider::_decode_unicode, avg 100µs/call
634 return {
63510137.60ms name => $alias,
636 path => $name,
637 text => $text,
638 time => $mtime,
639 load => $now,
640 };
641 }
642
643 return ( $error, Template::Constants::STATUS_ERROR )
644 unless $tolerant;
645 }
646
647 # Unable to process template, pass onto the next Provider.
6481554µs return (undef, Template::Constants::STATUS_DECLINED);
649}
650
651
652#------------------------------------------------------------------------
653# _refresh(\@slot)
654#
655# Private method called to mark a cache slot as most recently used.
656# A reference to the slot array should be passed by parameter. The
657# slot is relocated to the head of the linked list. If the file from
658# which the data was loaded has been updated since it was compiled, then
659# it is re-loaded from disk and re-compiled.
660#------------------------------------------------------------------------
661
662sub _refresh {
663 my ($self, $slot) = @_;
664 my $stat_ttl = $self->{ STAT_TTL };
665 my ($head, $file, $data, $error);
666
667 $self->debug("_refresh([ ",
668 join(', ', map { defined $_ ? $_ : '<undef>' } @$slot),
669 '])') if $self->{ DEBUG };
670
671 # if it's more than $STAT_TTL seconds since we last performed a
672 # stat() on the file then we need to do it again and see if the file
673 # time has changed
674 my $now = time;
675 my $expires_in_sec = $slot->[ STAT ] + $stat_ttl - $now;
676
677 if ( $expires_in_sec <= 0 ) { # Time to check!
678 $slot->[ STAT ] = $now;
679
680 # Grab mtime of template.
681 # Seems like this should be abstracted to compare to
682 # just ask for a newer compiled template (if it's newer)
683 # and let that check for a newer template source.
684 my $template_mtime = $self->_template_modified( $slot->[ NAME ] );
685 if ( ! defined $template_mtime || ( $template_mtime != $slot->[ LOAD ] )) {
686 $self->debug("refreshing cache file ", $slot->[ NAME ])
687 if $self->{ DEBUG };
688
689 ($data, $error) = $self->_load($slot->[ NAME ], $slot->[ DATA ]->{ name });
690 ($data, $error) = $self->_compile($data)
691 unless $error;
692
693 if ($error) {
694 # if the template failed to load/compile then we wipe out the
695 # STAT entry. This forces the provider to try and reload it
696 # each time instead of using the previously cached version
697 # until $STAT_TTL is next up
698 $slot->[ STAT ] = 0;
699 }
700 else {
701 $slot->[ DATA ] = $data->{ data };
702 $slot->[ LOAD ] = $data->{ time };
703 }
704 }
705
706 } elsif ( $self->{ DEBUG } ) {
707 $self->debug( sprintf('STAT_TTL not met for file [%s]. Expires in %d seconds',
708 $slot->[ NAME ], $expires_in_sec ) );
709 }
710
711 # Move this slot to the head of the list
712 unless( $self->{ HEAD } == $slot ) {
713 # remove existing slot from usage chain...
714 if ($slot->[ PREV ]) {
715 $slot->[ PREV ]->[ NEXT ] = $slot->[ NEXT ];
716 }
717 else {
718 $self->{ HEAD } = $slot->[ NEXT ];
719 }
720 if ($slot->[ NEXT ]) {
721 $slot->[ NEXT ]->[ PREV ] = $slot->[ PREV ];
722 }
723 else {
724 $self->{ TAIL } = $slot->[ PREV ];
725 }
726
727 # ..and add to start of list
728 $head = $self->{ HEAD };
729 $head->[ PREV ] = $slot if $head;
730 $slot->[ PREV ] = undef;
731 $slot->[ NEXT ] = $head;
732 $self->{ HEAD } = $slot;
733 }
734
735 return ($data, $error);
736}
737
- -
740#------------------------------------------------------------------------
741# _store($name, $data)
742#
743# Private method called to add a data item to the cache. If the cache
744# size limit has been reached then the oldest entry at the tail of the
745# list is removed and its slot relocated to the head of the list and
746# reused for the new data item. If the cache is under the size limit,
747# or if no size limit is defined, then the item is added to the head
748# of the list.
749# Returns compiled template
750#------------------------------------------------------------------------
751
752
# spent 92.6ms (40.7+51.8) within Template::Provider::_store which was called 1013 times, avg 91µs/call: # 1013 times (40.7ms+51.8ms) by Template::Provider::store at line 176, avg 91µs/call
sub _store {
75310131.16ms my ($self, $name, $data, $compfile) = @_;
75410131.85ms my $size = $self->{ SIZE };
7551013715µs my ($slot, $head);
756
757 # Return if memory cache disabled. (overriding code should also check)
758 # $$$ What's the expected behaviour of store()? Can't tell from the
759 # docs if you can call store() when SIZE = 0.
7601013707µs return $data->{data} if defined $size and !$size;
761
762 # extract the compiled template from the data hash
76310131.04ms $data = $data->{ data };
76410131.44ms $self->debug("_store($name, $data)") if $self->{ DEBUG };
765
766 # check the modification time -- extra stat here
76710134.67ms101351.8ms my $load = $self->_modified($name);
# spent 51.8ms making 1013 calls to Template::Provider::_modified, avg 51µs/call
768
76910131.43ms if (defined $size && $self->{ SLOTS } >= $size) {
770 # cache has reached size limit, so reuse oldest entry
771 $self->debug("reusing oldest cache entry (size limit reached: $size)\nslots: $self->{ SLOTS }") if $self->{ DEBUG };
772
773 # remove entry from tail of list
774 $slot = $self->{ TAIL };
775 $slot->[ PREV ]->[ NEXT ] = undef;
776 $self->{ TAIL } = $slot->[ PREV ];
777
778 # remove name lookup for old node
779 delete $self->{ LOOKUP }->{ $slot->[ NAME ] };
780
781 # add modified node to head of list
782 $head = $self->{ HEAD };
783 $head->[ PREV ] = $slot if $head;
784 @$slot = ( undef, $name, $data, $load, $head, time );
785 $self->{ HEAD } = $slot;
786
787 # add name lookup for new node
788 $self->{ LOOKUP }->{ $name } = $slot;
789 }
790 else {
791 # cache is under size limit, or none is defined
792
7931013882µs $self->debug("adding new cache entry") if $self->{ DEBUG };
794
795 # add new node to head of list
7961013885µs $head = $self->{ HEAD };
79710132.64ms $slot = [ undef, $name, $data, $load, $head, time ];
7981013372µs $head->[ PREV ] = $slot if $head;
79910131.43ms $self->{ HEAD } = $slot;
80010132.17ms $self->{ TAIL } = $slot unless $self->{ TAIL };
801
802 # add lookup from name to slot and increment nslots
80310132.57ms $self->{ LOOKUP }->{ $name } = $slot;
80410131.51ms $self->{ SLOTS }++;
805 }
806
80710139.31ms return $data;
808}
809
810
811#------------------------------------------------------------------------
812# _compile($data)
813#
814# Private method called to parse the template text and compile it into
815# a runtime form. Creates and delegates a Template::Parser object to
816# handle the compilation, or uses a reference passed in PARSER. On
817# success, the compiled template is stored in the 'data' item of the
818# $data hash and returned. On error, ($error, STATUS_ERROR) is returned,
819# or (undef, STATUS_DECLINED) if the TOLERANT flag is set.
820# The optional $compiled parameter may be passed to specify
821# the name of a compiled template file to which the generated Perl
822# code should be written. Errors are (for now...) silently
823# ignored, assuming that failures to open a file for writing are
824# intentional (e.g directory write permission).
825#------------------------------------------------------------------------
826
827
# spent 405s (13.4+392) within Template::Provider::_compile which was called 384174 times, avg 1.05ms/call: # 383161 times (13.4s+379s) by Template::Provider::fetch at line 130, avg 1.02ms/call # 1013 times (40.7ms+12.3s) by Template::Provider::_fetch at line 482, avg 12.2ms/call
sub _compile {
828384174194ms my ($self, $data, $compfile) = @_;
829384174559ms my $text = $data->{ text };
830384174117ms my ($parsedoc, $error);
831
832 $self->debug("_compile($data, ",
833 defined $compfile ? $compfile : '<no compfile>', ')')
834384174272ms if $self->{ DEBUG };
835
836 my $parser = $self->{ PARSER }
837 ||= Template::Config->parser($self->{ PARAMS })
8383841741.45s38316160.8s || return (Template::Config->error(), Template::Constants::STATUS_ERROR);
# spent 60.8s making 383161 calls to Template::Config::parser, avg 159µs/call
839
840 # discard the template text - we don't need it any more
841384174360ms delete $data->{ text };
842
843 # call parser to compile template into Perl code
8443841741.32s384174244s if ($parsedoc = $parser->parse($text, $data)) {
# spent 244s making 384174 calls to Template::Parser::parse, avg 634µs/call
845
846 $parsedoc->{ METADATA } = {
847 'name' => $data->{ name },
848 'modtime' => $data->{ time },
8493841741.45s %{ $parsedoc->{ METADATA } },
850 };
851
852 # write the Perl code to the file $compfile, if defined
853384174227ms if ($compfile) {
854 my $basedir = &File::Basename::dirname($compfile);
855 $basedir =~ /(.*)/;
856 $basedir = $1;
857
858 unless (-d $basedir) {
859 eval { File::Path::mkpath($basedir) };
860 $error = "failed to create compiled templates directory: $basedir ($@)"
861 if ($@);
862 }
863
864 unless ($error) {
865 my $docclass = $self->{ DOCUMENT };
866 $error = 'cache failed to write '
867 . &File::Basename::basename($compfile)
868 . ': ' . $docclass->error()
869 unless $docclass->write_perl_file($compfile, $parsedoc);
870 }
871
872 # set atime and mtime of newly compiled file, don't bother
873 # if time is undef
874 if (!defined($error) && defined $data->{ time }) {
875 my ($cfile) = $compfile =~ /^(.+)$/s or do {
876 return("invalid filename: $compfile",
877 Template::Constants::STATUS_ERROR);
878 };
879
880 my ($ctime) = $data->{ time } =~ /^(\d+)$/;
881 unless ($ctime || $ctime eq 0) {
882 return("invalid time: $ctime",
883 Template::Constants::STATUS_ERROR);
884 }
885 utime($ctime, $ctime, $cfile);
886
887 $self->debug(" cached compiled template to file [$compfile]")
888 if $self->{ DEBUG };
889 }
890 }
891
892384174204ms unless ($error) {
893 return $data ## RETURN ##
8943841745.14s38417487.3s if $data->{ data } = $DOCUMENT->new($parsedoc);
# spent 87.3s making 384174 calls to Template::Document::new, avg 227µs/call
895 $error = $Template::Document::ERROR;
896 }
897 }
898 else {
899 $error = Template::Exception->new( 'parse', "$data->{ name } " .
900 $parser->error() );
901 }
902
903 # return STATUS_ERROR, or STATUS_DECLINED if we're being tolerant
904 return $self->{ TOLERANT }
905 ? (undef, Template::Constants::STATUS_DECLINED)
906 : ($error, Template::Constants::STATUS_ERROR)
907}
908
909#------------------------------------------------------------------------
910# _compiled_is_current( $template_name )
911#
912# Returns true if $template_name and its compiled name
913# exist and they have the same mtime.
914#------------------------------------------------------------------------
915
916
# spent 13.7ms (7.24+6.51) within Template::Provider::_compiled_is_current which was called 1028 times, avg 13µs/call: # 1028 times (7.24ms+6.51ms) by Template::Provider::_fetch at line 460, avg 13µs/call
sub _compiled_is_current {
9171028841µs my ( $self, $template_name ) = @_;
91810285.63ms10286.51ms my $compiled_name = $self->_compiled_filename($template_name) || return;
# spent 6.51ms making 1028 calls to Template::Provider::_compiled_filename, avg 6µs/call
919 my $compiled_mtime = (stat($compiled_name))[9] || return;
920 my $template_mtime = $self->_template_modified( $template_name ) || return;
921
922 # This was >= in the 2.15, but meant that downgrading
923 # a source template would not get picked up.
924 return $compiled_mtime == $template_mtime;
925}
926
927
928#------------------------------------------------------------------------
929# _template_modified($path)
930#
931# Returns the last modified time of the $path.
932# Returns undef if the path does not exist.
933# Override if templates are not on disk, for example
934#------------------------------------------------------------------------
935
936
# spent 82.4ms (18.8+63.6) within Template::Provider::_template_modified which was called 2041 times, avg 40µs/call: # 1028 times (7.99ms+33.4ms) by Template::Provider::_load at line 630, avg 40µs/call # 1013 times (10.8ms+30.2ms) by Template::Provider::_modified at line 995, avg 40µs/call
sub _template_modified {
93720411.68ms my $self = shift;
93820411.70ms my $template = shift || return;
939204181.8ms204163.6ms return (stat( $template ))[9];
# spent 63.6ms making 2041 calls to Template::Provider::CORE:stat, avg 31µs/call
940}
941
942#------------------------------------------------------------------------
943# _template_content($path)
944#
945# Fetches content pointed to by $path.
946# Returns the content in scalar context.
947# Returns ($data, $error, $mtime) in list context where
948# $data - content
949# $error - error string if there was an error, otherwise undef
950# $mtime - last modified time from calling stat() on the path
951#------------------------------------------------------------------------
952
953
# spent 112ms (36.1+75.6) within Template::Provider::_template_content which was called 1013 times, avg 110µs/call: # 1013 times (36.1ms+75.6ms) by Template::Provider::_load at line 631, avg 110µs/call
sub _template_content {
9541013779µs my ($self, $path) = @_;
955
9561013618µs return (undef, "No path specified to fetch content from ")
957 unless $path;
958
9591013619µs my $data;
960 my $mod_date;
961 my $error;
962
96310132.53ms local *FH;
964101351.8ms202643.0ms if(-d $path) {
# spent 39.4ms making 1013 calls to Template::Provider::CORE:open, avg 39µs/call # spent 3.60ms making 1013 calls to Template::Provider::CORE:ftdir, avg 4µs/call
965 $error = "$path: not a file";
966 }
967 elsif (open(FH, "< $path")) {
96810133.85ms local $/;
96910134.82ms10131.94ms binmode(FH);
# spent 1.94ms making 1013 calls to Template::Provider::CORE:binmode, avg 2µs/call
970101322.6ms101318.9ms $data = <FH>;
# spent 18.9ms making 1013 calls to Template::Provider::CORE:readline, avg 19µs/call
97110135.94ms10132.60ms $mod_date = (stat($path))[9];
# spent 2.60ms making 1013 calls to Template::Provider::CORE:stat, avg 3µs/call
972101312.9ms10139.20ms close(FH);
# spent 9.20ms making 1013 calls to Template::Provider::CORE:close, avg 9µs/call
973 }
974 else {
975 $error = "$path: $!";
976 }
977
978 return wantarray
979101314.5ms ? ( $data, $error, $mod_date )
980 : $data;
981}
982
983
984#------------------------------------------------------------------------
985# _modified($name)
986# _modified($name, $time)
987#
988# When called with a single argument, it returns the modification time
989# of the named template. When called with a second argument it returns
990# true if $name has been modified since $time.
991#------------------------------------------------------------------------
992
993
# spent 51.8ms (10.9+41.0) within Template::Provider::_modified which was called 1013 times, avg 51µs/call: # 1013 times (10.9ms+41.0ms) by Template::Provider::_store at line 767, avg 51µs/call
sub _modified {
9941013856µs my ($self, $name, $time) = @_;
99510135.60ms101341.0ms my $load = $self->_template_modified($name)
# spent 41.0ms making 1013 calls to Template::Provider::_template_modified, avg 40µs/call
996 || return $time ? 1 : 0;
997
998101314.6ms return $time
999 ? $load > $time
1000 : $load;
1001}
1002
1003#------------------------------------------------------------------------
1004# _dump()
1005#
1006# Debug method which returns a string representing the internal object
1007# state.
1008#------------------------------------------------------------------------
1009
1010sub _dump {
1011 my $self = shift;
1012 my $size = $self->{ SIZE };
1013 my $parser = $self->{ PARSER };
1014 $parser = $parser ? $parser->_dump() : '<no parser>';
1015 $parser =~ s/\n/\n /gm;
1016 $size = 'unlimited' unless defined $size;
1017
1018 my $output = "[Template::Provider] {\n";
1019 my $format = " %-16s => %s\n";
1020 my $key;
1021
1022 $output .= sprintf($format, 'INCLUDE_PATH',
1023 '[ ' . join(', ', @{ $self->{ INCLUDE_PATH } }) . ' ]');
1024 $output .= sprintf($format, 'CACHE_SIZE', $size);
1025
1026 foreach $key (qw( ABSOLUTE RELATIVE TOLERANT DELIMITER
1027 COMPILE_EXT COMPILE_DIR )) {
1028 $output .= sprintf($format, $key, $self->{ $key });
1029 }
1030 $output .= sprintf($format, 'PARSER', $parser);
1031
1032
1033 local $" = ', ';
1034 my $lookup = $self->{ LOOKUP };
1035 $lookup = join('', map {
1036 sprintf(" $format", $_, defined $lookup->{ $_ }
1037 ? ('[ ' . join(', ', map { defined $_ ? $_ : '<undef>' }
1038 @{ $lookup->{ $_ } }) . ' ]') : '<undef>');
1039 } sort keys %$lookup);
1040 $lookup = "{\n$lookup }";
1041
1042 $output .= sprintf($format, LOOKUP => $lookup);
1043
1044 $output .= '}';
1045 return $output;
1046}
1047
1048
1049#------------------------------------------------------------------------
1050# _dump_cache()
1051#
1052# Debug method which prints the current state of the cache to STDERR.
1053#------------------------------------------------------------------------
1054
1055sub _dump_cache {
1056 my $self = shift;
1057 my ($node, $lut, $count);
1058
1059 $count = 0;
1060 if ($node = $self->{ HEAD }) {
1061 while ($node) {
1062 $lut->{ $node } = $count++;
1063 $node = $node->[ NEXT ];
1064 }
1065 $node = $self->{ HEAD };
1066 print STDERR "CACHE STATE:\n";
1067 print STDERR " HEAD: ", $self->{ HEAD }->[ NAME ], "\n";
1068 print STDERR " TAIL: ", $self->{ TAIL }->[ NAME ], "\n";
1069 while ($node) {
1070 my ($prev, $name, $data, $load, $next) = @$node;
1071# $name = '...' . substr($name, -10) if length $name > 10;
1072 $prev = $prev ? "#$lut->{ $prev }<-": '<undef>';
1073 $next = $next ? "->#$lut->{ $next }": '<undef>';
1074 print STDERR " #$lut->{ $node } : [ $prev, $name, $data, $load, $next ]\n";
1075 $node = $node->[ NEXT ];
1076 }
1077 }
1078}
1079
1080#------------------------------------------------------------------------
1081# _decode_unicode
1082#
1083# Decodes encoded unicode text that starts with a BOM and
1084# turns it into perl's internal representation
1085#------------------------------------------------------------------------
1086
1087
# spent 101ms (34.7+66.3) within Template::Provider::_decode_unicode which was called 1013 times, avg 100µs/call: # 1013 times (34.7ms+66.3ms) by Template::Provider::_load at line 633, avg 100µs/call
sub _decode_unicode {
10881013517µs my $self = shift;
10891013750µs my $string = shift;
10901013515µs return undef unless defined $string;
1091
10922172µs226µs
# spent 22µs (18+4) within Template::Provider::BEGIN@1092 which was called: # once (18µs+4µs) by Template::BEGIN@29 at line 1092
use bytes;
# spent 22µs making 1 call to Template::Provider::BEGIN@1092 # spent 4µs making 1 call to bytes::import
109310131.47ms require Encode;
1094
1095101314.3ms10132.62ms return $string if Encode::is_utf8( $string );
# spent 2.62ms making 1013 calls to Encode::is_utf8, avg 3µs/call
1096
1097 # try all the BOMs in order looking for one (order is important
1098 # 32bit BOMs look like 16bit BOMs)
1099
11001013703µs my $count = 0;
1101
110210131.49ms while ($count < @{ $boms }) {
110350653.39ms my $enc = $boms->[$count++];
110450653.63ms my $bom = $boms->[$count++];
1105
1106 # does the string start with the bom?
110750653.87ms if ($bom eq substr($string, 0, length($bom))) {
1108 # decode it and hand it back
1109 return Encode::decode($enc, substr($string, length($bom)), 1);
1110 }
1111 }
1112
1113 return $self->{ ENCODING }
1114101314.3ms101363.6ms ? Encode::decode( $self->{ ENCODING }, $string )
# spent 63.6ms making 1013 calls to Encode::decode, avg 63µs/call
1115 : $string;
1116}
1117
1118
111918µs1;
1120
1121__END__
 
# spent 1.94ms within Template::Provider::CORE:binmode which was called 1013 times, avg 2µs/call: # 1013 times (1.94ms+0s) by Template::Provider::_template_content at line 969, avg 2µs/call
sub Template::Provider::CORE:binmode; # opcode
# spent 9.20ms within Template::Provider::CORE:close which was called 1013 times, avg 9µs/call: # 1013 times (9.20ms+0s) by Template::Provider::_template_content at line 972, avg 9µs/call
sub Template::Provider::CORE:close; # opcode
# spent 3.60ms within Template::Provider::CORE:ftdir which was called 1013 times, avg 4µs/call: # 1013 times (3.60ms+0s) by Template::Provider::_template_content at line 964, avg 4µs/call
sub Template::Provider::CORE:ftdir; # opcode
# spent 1.30ms within Template::Provider::CORE:match which was called 1013 times, avg 1µs/call: # 1013 times (1.30ms+0s) by Template::Provider::fetch at line 127, avg 1µs/call
sub Template::Provider::CORE:match; # opcode
# spent 39.4ms within Template::Provider::CORE:open which was called 1013 times, avg 39µs/call: # 1013 times (39.4ms+0s) by Template::Provider::_template_content at line 964, avg 39µs/call
sub Template::Provider::CORE:open; # opcode
# spent 3µs within Template::Provider::CORE:qr which was called: # once (3µs+0s) by Template::BEGIN@29 at line 82
sub Template::Provider::CORE:qr; # opcode
# spent 18.9ms within Template::Provider::CORE:readline which was called 1013 times, avg 19µs/call: # 1013 times (18.9ms+0s) by Template::Provider::_template_content at line 970, avg 19µs/call
sub Template::Provider::CORE:readline; # opcode
# spent 700ms within Template::Provider::CORE:regcomp which was called 384174 times, avg 2µs/call: # 383161 times (700ms+0s) by Template::Provider::_init at line 354, avg 2µs/call # 1013 times (445µs+0s) by Template::Provider::fetch at line 127, avg 440ns/call
sub Template::Provider::CORE:regcomp; # opcode
# spent 66.2ms within Template::Provider::CORE:stat which was called 3054 times, avg 22µs/call: # 2041 times (63.6ms+0s) by Template::Provider::_template_modified at line 939, avg 31µs/call # 1013 times (2.60ms+0s) by Template::Provider::_template_content at line 971, avg 3µs/call
sub Template::Provider::CORE:stat; # opcode
# spent 2µs within Template::Provider::__ANON__ which was called 3 times, avg 600ns/call: # once (900ns+0s) by Template::Provider::BEGIN@46 at line 46 # once (500ns+0s) by Template::Provider::BEGIN@44 at line 44 # once (400ns+0s) by Template::Provider::BEGIN@48 at line 48
sub Template::Provider::__ANON__; # xsub