From 69f55d37bb88d03805ed6788531b21b15bd92d1f Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 21 Nov 2011 15:58:06 +0100 Subject: [PATCH 1/3] Generate literal ids only once and use in equals() Significant speedup because equals and getId() are called so frequently. --- src/Composer/DependencyResolver/Literal.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Composer/DependencyResolver/Literal.php b/src/Composer/DependencyResolver/Literal.php index 39f0e4cc5..1870e9a71 100644 --- a/src/Composer/DependencyResolver/Literal.php +++ b/src/Composer/DependencyResolver/Literal.php @@ -25,6 +25,7 @@ class Literal { $this->package = $package; $this->wanted = $wanted; + $this->id = ($this->wanted ? '' : '-') . $this->package->getId(); } public function isWanted() @@ -44,7 +45,7 @@ class Literal public function getId() { - return ($this->wanted ? '' : '-') . $this->package->getId(); + return $this->id; } public function __toString() @@ -59,6 +60,6 @@ class Literal public function equals(Literal $b) { - return $this->getId() === $b->getId(); + return $this->id === $b->id; } } From 40b33914b362f2c4c10aa92643c284316c38310f Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 21 Nov 2011 16:01:48 +0100 Subject: [PATCH 2/3] Compute rule hashes for faster duplicate detection --- src/Composer/DependencyResolver/Rule.php | 15 ++++++++++++- src/Composer/DependencyResolver/RuleSet.php | 25 +++++++++++++++++++++ src/Composer/DependencyResolver/Solver.php | 6 ++--- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/Composer/DependencyResolver/Rule.php b/src/Composer/DependencyResolver/Rule.php index 64a3106d2..d08c4a5ed 100644 --- a/src/Composer/DependencyResolver/Rule.php +++ b/src/Composer/DependencyResolver/Rule.php @@ -45,6 +45,15 @@ class Rule $this->watch2 = (count($this->literals) > 1) ? $literals[1]->getId() : 0; $this->type = -1; + + $this->ruleHash = substr(md5(implode(',', array_map(function ($l) { + return $l->getId(); + }, $this->literals))), 0, 5); + } + + public function getHash() + { + return $this->ruleHash; } public function setId($id) @@ -67,12 +76,16 @@ class Rule */ public function equals(Rule $rule) { + if ($this->ruleHash !== $rule->ruleHash) { + return false; + } + if (count($this->literals) != count($rule->literals)) { return false; } for ($i = 0, $n = count($this->literals); $i < $n; $i++) { - if (!$this->literals[$i]->equals($rule->literals[$i])) { + if (!$this->literals[$i]->getId() === $rule->literals[$i]->getId()) { return false; } } diff --git a/src/Composer/DependencyResolver/RuleSet.php b/src/Composer/DependencyResolver/RuleSet.php index cc57f8e22..49a7c2536 100644 --- a/src/Composer/DependencyResolver/RuleSet.php +++ b/src/Composer/DependencyResolver/RuleSet.php @@ -39,6 +39,8 @@ class RuleSet implements \IteratorAggregate, \Countable protected $ruleById; protected $nextRuleId; + protected $rulesByHash; + public function __construct() { $this->nextRuleId = 0; @@ -46,6 +48,8 @@ class RuleSet implements \IteratorAggregate, \Countable foreach ($this->getTypes() as $type) { $this->rules[$type] = array(); } + + $this->rulesByHash = array(); } public function add(Rule $rule, $type) @@ -64,6 +68,13 @@ class RuleSet implements \IteratorAggregate, \Countable $rule->setId($this->nextRuleId); $this->nextRuleId++; + + $hash = $rule->getHash(); + if (!isset($this->rulesByHash[$hash])) { + $this->rulesByHash[$hash] = array($rule); + } else { + $this->rulesByHash[$hash][] = $rule; + } } public function count() @@ -129,6 +140,20 @@ class RuleSet implements \IteratorAggregate, \Countable return array_keys($types); } + public function containsEqual($rule) + { + if (isset($this->rulesByHash[$rule->getHash()])) { + $potentialDuplicates = $this->rulesByHash[$rule->getHash()]; + foreach ($potentialDuplicates as $potentialDuplicate) { + if ($rule->equals($potentialDuplicate)) { + return true; + } + } + } + + return false; + } + public function __toString() { $string = "\n"; diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index ba15144cd..1ab152bcc 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -229,10 +229,8 @@ class Solver */ private function addRule($type, Rule $newRule = null) { if ($newRule) { - foreach ($this->rules->getIterator() as $rule) { - if ($rule->equals($newRule)) { - return; - } + if ($this->rules->containsEqual($newRule)) { + return; } $this->rules->add($newRule, $type); From 5d5d6462e31dd7a365884f663e4a4dee65937ab8 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 21 Nov 2011 16:13:23 +0100 Subject: [PATCH 3/3] Correctly declare all literal properties --- src/Composer/DependencyResolver/Literal.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Composer/DependencyResolver/Literal.php b/src/Composer/DependencyResolver/Literal.php index 1870e9a71..7234b5857 100644 --- a/src/Composer/DependencyResolver/Literal.php +++ b/src/Composer/DependencyResolver/Literal.php @@ -19,7 +19,9 @@ use Composer\Package\PackageInterface; */ class Literal { + protected $package; protected $wanted; + protected $id; public function __construct(PackageInterface $package, $wanted) {