From 15d572da4c2488acc6956dcaa76157da0781f03a Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Wed, 8 Jul 2015 18:36:49 +0200 Subject: [PATCH 1/3] Use 4 byte integer from raw md5 instead of 5 hex representation chars The hash is necessary as comparisons are significantly too slow otherwise. The old hash function used substr on the hexadecimal representation of the md5 hash, rather than the raw binary output. This wastes a significant amount of memory, as each byte can only be used to store up to 4 bit of information. The new hash has 32bit instead of 20bit and uses only a 4 byte integer instead of a 5 byte string. --- src/Composer/DependencyResolver/Rule.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Composer/DependencyResolver/Rule.php b/src/Composer/DependencyResolver/Rule.php index 37db43745..fe5085ae4 100644 --- a/src/Composer/DependencyResolver/Rule.php +++ b/src/Composer/DependencyResolver/Rule.php @@ -55,12 +55,11 @@ class Rule $this->reasonData = $reasonData; $this->disabled = false; - $this->job = $job; - $this->type = -1; - $this->ruleHash = substr(md5(implode(',', $this->literals)), 0, 5); + $data = unpack('ihash', md5(implode(',', $this->literals), true)); + $this->ruleHash = $data['hash']; } public function getHash() From c7e1f49e783f92960441b88fe23bc1e933797daa Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Wed, 8 Jul 2015 19:11:05 +0200 Subject: [PATCH 2/3] Rule hashes are only used in the rule set, so no need to store them --- src/Composer/DependencyResolver/Rule.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/Composer/DependencyResolver/Rule.php b/src/Composer/DependencyResolver/Rule.php index fe5085ae4..a19c121c2 100644 --- a/src/Composer/DependencyResolver/Rule.php +++ b/src/Composer/DependencyResolver/Rule.php @@ -43,8 +43,6 @@ class Rule protected $job; - protected $ruleHash; - public function __construct(array $literals, $reason, $reasonData, $job = null) { // sort all packages ascending by id @@ -58,13 +56,12 @@ class Rule $this->job = $job; $this->type = -1; - $data = unpack('ihash', md5(implode(',', $this->literals), true)); - $this->ruleHash = $data['hash']; } public function getHash() { - return $this->ruleHash; + $data = unpack('ihash', md5(implode(',', $this->literals), true)); + return $data['hash']; } public function setId($id) @@ -113,10 +110,6 @@ class Rule */ public function equals(Rule $rule) { - if ($this->ruleHash !== $rule->ruleHash) { - return false; - } - if (count($this->literals) != count($rule->literals)) { return false; } From b869fa9662f8f750d3a11dd5e4c7d3b19c947c5b Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Wed, 8 Jul 2015 19:36:13 +0200 Subject: [PATCH 3/3] Correct rule hash test --- tests/Composer/Test/DependencyResolver/RuleTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Composer/Test/DependencyResolver/RuleTest.php b/tests/Composer/Test/DependencyResolver/RuleTest.php index 6688b24aa..4382987eb 100644 --- a/tests/Composer/Test/DependencyResolver/RuleTest.php +++ b/tests/Composer/Test/DependencyResolver/RuleTest.php @@ -30,7 +30,8 @@ class RuleTest extends TestCase { $rule = new Rule(array(123), 'job1', null); - $this->assertEquals(substr(md5('123'), 0, 5), $rule->getHash()); + $hash = unpack('ihash', md5('123', true)); + $this->assertEquals($hash['hash'], $rule->getHash()); } public function testSetAndGetId()