From 40b33914b362f2c4c10aa92643c284316c38310f Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 21 Nov 2011 16:01:48 +0100 Subject: [PATCH] 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);