From 08ecb0e1c418c75b3dc50fe3894251529f2bc523 Mon Sep 17 00:00:00 2001 From: Florin Patan Date: Tue, 18 Sep 2012 22:27:45 +0300 Subject: [PATCH] Improvements for loader speeds --- lib/Twig/Error.php | 2 + lib/Twig/ExtendedLoaderInterface.php | 31 +++++++++++++++++ lib/Twig/Loader/Array.php | 27 +++++++-------- lib/Twig/Loader/Chain.php | 60 +++++++++++++++++++++++++-------- lib/Twig/Loader/Filesystem.php | 41 ++++++++++++++-------- lib/Twig/Loader/String.php | 21 ++++++------ 6 files changed, 127 insertions(+), 55 deletions(-) create mode 100644 lib/Twig/ExtendedLoaderInterface.php diff --git a/lib/Twig/Error.php b/lib/Twig/Error.php index b5ac00e..3e61c3f 100644 --- a/lib/Twig/Error.php +++ b/lib/Twig/Error.php @@ -112,6 +112,8 @@ class Twig_Error extends Exception * @param array $arguments The parameters to be passed to the method * * @return Exception The previous exception or null + * + * @throws BadMethodCallException */ public function __call($method, $arguments) { diff --git a/lib/Twig/ExtendedLoaderInterface.php b/lib/Twig/ExtendedLoaderInterface.php new file mode 100644 index 0000000..8d59867 --- /dev/null +++ b/lib/Twig/ExtendedLoaderInterface.php @@ -0,0 +1,31 @@ + + */ +interface Twig_ExtendedLoaderInterface +{ + + /** + * Check if we have the source code of a template, given its name. + * + * @param string $name The name of the template to check if we can load + * + * @return boolean If the template source code is handled by this loader or not + */ + public function exists($name); + +} diff --git a/lib/Twig/Loader/Array.php b/lib/Twig/Loader/Array.php index 8776264..dfaf701 100644 --- a/lib/Twig/Loader/Array.php +++ b/lib/Twig/Loader/Array.php @@ -20,7 +20,7 @@ * @package twig * @author Fabien Potencier */ -class Twig_Loader_Array implements Twig_LoaderInterface +class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExtendedLoaderInterface { protected $templates; @@ -51,11 +51,7 @@ class Twig_Loader_Array implements Twig_LoaderInterface } /** - * Gets the source code of a template, given its name. - * - * @param string $name The name of the template to load - * - * @return string The template source code + * {@inheritdoc} */ public function getSource($name) { @@ -68,11 +64,15 @@ class Twig_Loader_Array implements Twig_LoaderInterface } /** - * Gets the cache key to use for the cache for a given template name. - * - * @param string $name The name of the template to load - * - * @return string The cache key + * {@inheritdoc} + */ + public function exists($name) + { + return isset($this->templates[(string) $name]); + } + + /** + * {@inheritdoc} */ public function getCacheKey($name) { @@ -85,10 +85,7 @@ class Twig_Loader_Array implements Twig_LoaderInterface } /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * {@inheritdoc} */ public function isFresh($name, $time) { diff --git a/lib/Twig/Loader/Chain.php b/lib/Twig/Loader/Chain.php index b6b0ce9..fd767c2 100644 --- a/lib/Twig/Loader/Chain.php +++ b/lib/Twig/Loader/Chain.php @@ -15,8 +15,9 @@ * @package twig * @author Fabien Potencier */ -class Twig_Loader_Chain implements Twig_LoaderInterface +class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExtendedLoaderInterface { + private $hasSourceCache = array(); protected $loaders; /** @@ -40,19 +41,20 @@ class Twig_Loader_Chain implements Twig_LoaderInterface public function addLoader(Twig_LoaderInterface $loader) { $this->loaders[] = $loader; + $this->hasSourceCache = array(); } /** - * Gets the source code of a template, given its name. - * - * @param string $name The name of the template to load - * - * @return string The template source code + * {@inheritdoc} */ public function getSource($name) { $exceptions = array(); foreach ($this->loaders as $loader) { + if ($loader instanceof Twig_ExtendedLoaderInterface && !$loader->exists($name)) { + continue; + } + try { return $loader->getSource($name); } catch (Twig_Error_Loader $e) { @@ -64,16 +66,43 @@ class Twig_Loader_Chain implements Twig_LoaderInterface } /** - * Gets the cache key to use for the cache for a given template name. - * - * @param string $name The name of the template to load - * - * @return string The cache key + * {@inheritdoc} + */ + public function exists($name) + { + if (isset($this->hasSourceCache[$name])) { + return $this->hasSourceCache[$name]; + } + + foreach ($this->loaders as $loader) { + if ($loader instanceof Twig_ExtendedLoaderInterface) { + if ($loader->exists($name)) { + return $this->hasSourceCache[$name] = true; + } + } else { + try { + $loader->getSource($name); + return $this->hasSourceCache[$name] = true; + } catch (Twig_Error_Loader $e) { + + } + } + } + + return $this->hasSourceCache[$name] = false; + } + + /** + * {@inheritdoc} */ public function getCacheKey($name) { $exceptions = array(); foreach ($this->loaders as $loader) { + if ($loader instanceof Twig_ExtendedLoaderInterface && !$loader->exists($name)) { + continue; + } + try { return $loader->getCacheKey($name); } catch (Twig_Error_Loader $e) { @@ -85,15 +114,16 @@ class Twig_Loader_Chain implements Twig_LoaderInterface } /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * {@inheritdoc} */ public function isFresh($name, $time) { $exceptions = array(); foreach ($this->loaders as $loader) { + if ($loader instanceof Twig_ExtendedLoaderInterface && !$loader->exists($name)) { + continue; + } + try { return $loader->isFresh($name, $time); } catch (Twig_Error_Loader $e) { diff --git a/lib/Twig/Loader/Filesystem.php b/lib/Twig/Loader/Filesystem.php index eb9c7cd..9e8b503 100644 --- a/lib/Twig/Loader/Filesystem.php +++ b/lib/Twig/Loader/Filesystem.php @@ -15,7 +15,7 @@ * @package twig * @author Fabien Potencier */ -class Twig_Loader_Filesystem implements Twig_LoaderInterface +class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExtendedLoaderInterface { protected $paths; protected $cache; @@ -77,6 +77,8 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface * * @param string $path A path where to look for templates * @param string $namespace A path name + * + * @throws Twig_Error_Loader */ public function addPath($path, $namespace = '__main__') { @@ -95,6 +97,8 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface * * @param string $path A path where to look for templates * @param string $namespace A path name + * + * @throws Twig_Error_Loader */ public function prependPath($path, $namespace = '__main__') { @@ -115,11 +119,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface } /** - * Gets the source code of a template, given its name. - * - * @param string $name The name of the template to load - * - * @return string The template source code + * {@inheritdoc} */ public function getSource($name) { @@ -127,11 +127,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface } /** - * Gets the cache key to use for the cache for a given template name. - * - * @param string $name The name of the template to load - * - * @return string The cache key + * {@inheritdoc} */ public function getCacheKey($name) { @@ -139,10 +135,25 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface } /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * {@inheritdoc} + */ + public function exists($name) + { + if (isset($this->cache[$name])) { + return true; + } + + try { + $this->findTemplate($name); + + return true; + } catch (Twig_Error_Loader $exception) { + return false; + } + } + + /** + * {@inheritdoc} */ public function isFresh($name, $time) { diff --git a/lib/Twig/Loader/String.php b/lib/Twig/Loader/String.php index a103bce..04742cd 100644 --- a/lib/Twig/Loader/String.php +++ b/lib/Twig/Loader/String.php @@ -24,14 +24,10 @@ * @package twig * @author Fabien Potencier */ -class Twig_Loader_String implements Twig_LoaderInterface +class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExtendedLoaderInterface { /** - * Gets the source code of a template, given its name. - * - * @param string $name The name of the template to load - * - * @return string The template source code + * {@inheritdoc} */ public function getSource($name) { @@ -39,6 +35,14 @@ class Twig_Loader_String implements Twig_LoaderInterface } /** + * {@inheritdoc} + */ + public function exists($name) + { + return true; + } + + /** * Gets the cache key to use for the cache for a given template name. * * @param string $name The name of the template to load @@ -51,10 +55,7 @@ class Twig_Loader_String implements Twig_LoaderInterface } /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * {@inheritdoc} */ public function isFresh($name, $time) { -- 1.7.2.5