Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Merge pull request zendframework/zendframework#6747 from nickpeirson/…
Browse files Browse the repository at this point in the history
…DI-DefinitionList-Optimisation

DI definition list optimisation - Cache classes upfront where possible to reduce iterations
  • Loading branch information
weierophinney committed Feb 23, 2015
2 parents 706768f + 2f15eca commit 1649e08
Showing 1 changed file with 106 additions and 14 deletions.
120 changes: 106 additions & 14 deletions src/DefinitionList.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,27 @@
namespace Zend\Di;

use SplDoublyLinkedList;
use Zend\Di\Definition\RuntimeDefinition;

/**
* Class definition based on multiple definitions
*/
class DefinitionList extends SplDoublyLinkedList implements Definition\DefinitionInterface
{
protected $classes = array();
protected $runtimeDefinitions;

/**
* @param Definition\DefinitionInterface|Definition\DefinitionInterface[] $definitions
*/
public function __construct($definitions)
{
$this->runtimeDefinitions = new SplDoublyLinkedList();
if (!is_array($definitions)) {
$definitions = array($definitions);
}
foreach ($definitions as $definition) {
$this->push($definition);
$this->addDefinition($definition, true);
}
}

Expand All @@ -45,6 +50,35 @@ public function addDefinition(Definition\DefinitionInterface $definition, $addTo
}
}

protected function getDefinitionClassMap(Definition\DefinitionInterface $definition)
{
$definitionClasses = $definition->getClasses();
if (empty($definitionClasses)) {
return array();
}
return array_combine(array_values($definitionClasses), array_fill(0, count($definitionClasses), $definition));
}

public function unshift($definition)
{
$result = parent::unshift($definition);
if ($definition instanceof RuntimeDefinition) {
$this->runtimeDefinitions->unshift($definition);
}
$this->classes = array_merge($this->classes, $this->getDefinitionClassMap($definition));
return $result;
}

public function push($definition)
{
$result = parent::push($definition);
if ($definition instanceof RuntimeDefinition) {
$this->runtimeDefinitions->push($definition);
}
$this->classes = array_merge($this->getDefinitionClassMap($definition), $this->classes);
return $result;
}

/**
* @param string $type
* @return Definition\DefinitionInterface[]
Expand Down Expand Up @@ -84,8 +118,11 @@ public function getDefinitionByType($type)
*/
public function getDefinitionForClass($class)
{
if (array_key_exists($class, $this->classes)) {
return $this->classes[$class];
}
/** @var $definition Definition\DefinitionInterface */
foreach ($this as $definition) {
foreach ($this->runtimeDefinitions as $definition) {
if ($definition->hasClass($class)) {
return $definition;
}
Expand All @@ -108,22 +145,19 @@ public function forClass($class)
*/
public function getClasses()
{
$classes = array();
/** @var $definition Definition\DefinitionInterface */
foreach ($this as $definition) {
$classes = array_merge($classes, $definition->getClasses());
}

return $classes;
return array_keys($this->classes);
}

/**
* {@inheritDoc}
*/
public function hasClass($class)
{
if (array_key_exists($class, $this->classes)) {
return true;
}
/** @var $definition Definition\DefinitionInterface */
foreach ($this as $definition) {
foreach ($this->runtimeDefinitions as $definition) {
if ($definition->hasClass($class)) {
return true;
}
Expand All @@ -137,9 +171,18 @@ public function hasClass($class)
*/
public function getClassSupertypes($class)
{
$supertypes = array();
if (!($classDefinition = $this->getDefinitionForClass($class))) {
return array();
}
$supertypes = $classDefinition->getClassSupertypes($class);
if(!($classDefinition instanceof Definition\PartialMarker)) {
return $supertypes;
}
/** @var $definition Definition\DefinitionInterface */
foreach ($this as $definition) {
if ($definition === $classDefinition) {
continue;
}
if ($definition->hasClass($class)) {
$supertypes = array_merge($supertypes, $definition->getClassSupertypes($class));
if ($definition instanceof Definition\PartialMarker) {
Expand All @@ -157,8 +200,21 @@ public function getClassSupertypes($class)
*/
public function getInstantiator($class)
{
if (!($classDefinition = $this->getDefinitionForClass($class))) {
return false;
}
$value = $classDefinition->getInstantiator($class);
if (!is_null($value)){
return $value;
}
if(!($classDefinition instanceof Definition\PartialMarker)) {
return false;
}
/** @var $definition Definition\DefinitionInterface */
foreach ($this as $definition) {
if ($definition === $classDefinition) {
continue;
}
if ($definition->hasClass($class)) {
$value = $definition->getInstantiator($class);
if ($value === null && $definition instanceof Definition\PartialMarker) {
Expand All @@ -177,8 +233,20 @@ public function getInstantiator($class)
*/
public function hasMethods($class)
{
if (!($classDefinition = $this->getDefinitionForClass($class))) {
return false;
}
if (false !== ($methods = $classDefinition->hasMethods($class))){
return $methods;
}
if(!($classDefinition instanceof Definition\PartialMarker)) {
return false;
}
/** @var $definition Definition\DefinitionInterface */
foreach ($this as $definition) {
if ($definition === $classDefinition) {
continue;
}
if ($definition->hasClass($class)) {
if ($definition->hasMethods($class) === false && $definition instanceof Definition\PartialMarker) {
continue;
Expand All @@ -199,9 +267,15 @@ public function hasMethod($class, $method)
if (!$this->hasMethods($class)) {
return false;
}

$classDefinition = $this->getDefinitionForClass($class);
if ($classDefinition->hasMethod($class, $method)) {
return true;
}
/** @var $definition Definition\DefinitionInterface */
foreach ($this as $definition) {
foreach ($this->runtimeDefinitions as $definition) {
if ($definition === $classDefinition) {
continue;
}
if ($definition->hasClass($class) && $definition->hasMethod($class, $method)) {
return true;
}
Expand All @@ -215,9 +289,18 @@ public function hasMethod($class, $method)
*/
public function getMethods($class)
{
if (!($classDefinition = $this->getDefinitionForClass($class))) {
return array();
}
$methods = $classDefinition->getMethods($class);
if(!($classDefinition instanceof Definition\PartialMarker)) {
return $methods;
}
/** @var $definition Definition\DefinitionInterface */
$methods = array();
foreach ($this as $definition) {
if ($definition === $classDefinition) {
continue;
}
if ($definition->hasClass($class)) {
if (!$definition instanceof Definition\PartialMarker) {
return array_merge($definition->getMethods($class), $methods);
Expand Down Expand Up @@ -245,8 +328,17 @@ public function hasMethodParameters($class, $method)
*/
public function getMethodParameters($class, $method)
{
if (!($classDefinition = $this->getDefinitionForClass($class))) {
return array();
}
if ($classDefinition->hasMethod($class, $method) && $classDefinition->hasMethodParameters($class, $method)) {
return $classDefinition->getMethodParameters($class, $method);
}
/** @var $definition Definition\DefinitionInterface */
foreach ($this as $definition) {
if ($definition === $classDefinition) {
continue;
}
if ($definition->hasClass($class) && $definition->hasMethod($class, $method) && $definition->hasMethodParameters($class, $method)) {
return $definition->getMethodParameters($class, $method);
}
Expand Down

0 comments on commit 1649e08

Please sign in to comment.