Skip to content

Commit

Permalink
[OptionsResolver] Removed LazyOption class and improved performance a…
Browse files Browse the repository at this point in the history
… tiny bit
  • Loading branch information
webmozart committed Jul 29, 2012
1 parent 50652a9 commit 27ab56d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 142 deletions.
73 changes: 0 additions & 73 deletions src/Symfony/Component/OptionsResolver/LazyOption.php

This file was deleted.

62 changes: 37 additions & 25 deletions src/Symfony/Component/OptionsResolver/Options.php
Expand Up @@ -21,7 +21,7 @@
class Options implements \ArrayAccess, \Iterator, \Countable
{
/**
* A list of option values and LazyOption instances.
* A list of option values.
* @var array
*/
private $options = array();
Expand All @@ -33,19 +33,13 @@ class Options implements \ArrayAccess, \Iterator, \Countable
private $normalizers = array();

/**
* A list storing the names of all options that need to be normalized.
* @var array
*/
private $normalization = array();

/**
* A list storing the names of all LazyOption instances as keys.
* A list of closures for evaluating lazy options.
* @var array
*/
private $lazy = array();

/**
* A list of Boolean locks for each LazyOption.
* A list containing the currently locked options.
* @var array
*/
private $lock = array();
Expand Down Expand Up @@ -95,6 +89,7 @@ public function set($option, $value)
// Setting is equivalent to overloading while discarding the previous
// option value
unset($this->options[$option]);
unset($this->lazy[$option]);

$this->overload($option, $value);
}
Expand Down Expand Up @@ -126,9 +121,6 @@ public function setNormalizer($option, \Closure $normalizer)
}

$this->normalizers[$option] = $normalizer;

// Each option for which a normalizer exists needs to be normalized
$this->normalization[$option] = true;
}

/**
Expand All @@ -150,6 +142,7 @@ public function replace(array $options)
}

$this->options = array();
$this->lazy = array();

foreach ($options as $option => $value) {
$this->overload($option, $value);
Expand Down Expand Up @@ -184,25 +177,30 @@ public function overload($option, $value)
}

// If an option is a closure that should be evaluated lazily, store it
// inside a LazyOption instance.
// in the "lazy" property.
if ($value instanceof \Closure) {
$reflClosure = new \ReflectionFunction($value);
$params = $reflClosure->getParameters();

if (isset($params[0]) && null !== ($class = $params[0]->getClass()) && __CLASS__ === $class->name) {
$currentValue = isset($params[1]) && isset($this->options[$option]) ? $this->options[$option] : null;
$value = new LazyOption($value, $currentValue);
// Initialize the option if no previous value exists
if (!isset($this->options[$option])) {
$this->options[$option] = null;
}

// Store which options are lazy for more efficient resolving
$this->lazy[$option] = true;
// Ignore previous lazy options if the closure has no second parameter
if (!isset($this->lazy[$option]) || !isset($params[1])) {
$this->lazy[$option] = array();
}

$this->options[$option] = $value;
// Store closure for later evaluation
$this->lazy[$option][] = $value;

return;
}
}

// Reset lazy flag and locks by default
// Remove lazy options by default
unset($this->lazy[$option]);

$this->options[$option] = $value;
Expand Down Expand Up @@ -233,7 +231,7 @@ public function get($option)
$this->resolve($option);
}

if (isset($this->normalization[$option])) {
if (isset($this->normalizers[$option])) {
$this->normalize($option);
}

Expand Down Expand Up @@ -269,6 +267,7 @@ public function remove($option)

unset($this->options[$option]);
unset($this->lazy[$option]);
unset($this->normalizers[$option]);
}

/**
Expand All @@ -286,6 +285,7 @@ public function clear()

$this->options = array();
$this->lazy = array();
$this->normalizers = array();
}

/**
Expand All @@ -301,14 +301,16 @@ public function all()

// Performance-wise this is slightly better than
// while (null !== $option = key($this->lazy))
foreach ($this->lazy as $option => $isLazy) {
foreach ($this->lazy as $option => $closures) {
// Double check, in case the option has already been resolved
// by cascade in the previous cycles
if (isset($this->lazy[$option])) {
$this->resolve($option);
}
}

foreach ($this->normalization as $option => $normalize) {
if (isset($this->normalization[$option])) {
foreach ($this->normalizers as $option => $normalizer) {
if (isset($this->normalizers[$option])) {
$this->normalize($option);
}
}
Expand Down Expand Up @@ -443,6 +445,10 @@ public function count()
*/
private function resolve($option)
{
// The code duplication with normalize() exists for performance
// reasons, in order to save a method call.
// Remember that this method is potentially called a couple of thousand
// times and needs to be as efficient as possible.
if (isset($this->lock[$option])) {
$conflicts = array();

Expand All @@ -456,7 +462,9 @@ private function resolve($option)
}

$this->lock[$option] = true;
$this->options[$option] = $this->options[$option]->evaluate($this);
foreach ($this->lazy[$option] as $closure) {
$this->options[$option] = $closure($this, $this->options[$option]);
}
unset($this->lock[$option]);

// The option now isn't lazy anymore
Expand All @@ -475,6 +483,10 @@ private function resolve($option)
*/
private function normalize($option)
{
// The code duplication with resolve() exists for performance
// reasons, in order to save a method call.
// Remember that this method is potentially called a couple of thousand
// times and needs to be as efficient as possible.
if (isset($this->lock[$option])) {
$conflicts = array();

Expand All @@ -495,6 +507,6 @@ private function normalize($option)
unset($this->lock[$option]);

// The option is now normalized
unset($this->normalization[$option]);
unset($this->normalizers[$option]);
}
}
44 changes: 0 additions & 44 deletions src/Symfony/Component/OptionsResolver/Tests/LazyOptionTest.php

This file was deleted.

0 comments on commit 27ab56d

Please sign in to comment.