Эх сурвалжийг харах

Reduce memory footprint of rules by storing data in blob

Not declaring the job property saves significant amounts of memory as
most rules leave it as null
Nils Adermann 10 жил өмнө
parent
commit
6e81f63635

+ 1 - 1
src/Composer/DependencyResolver/Problem.php

@@ -47,7 +47,7 @@ class Problem
      */
     public function addRule(Rule $rule)
     {
-        $this->addReason($rule->getId(), array(
+        $this->addReason(spl_object_hash($rule), array(
             'rule' => $rule,
             'job' => $rule->getJob(),
         ));

+ 30 - 31
src/Composer/DependencyResolver/Rule.php

@@ -35,27 +35,22 @@ class Rule
      */
     public $literals;
 
-    protected $disabled;
-    protected $type;
-    protected $id;
-    protected $reason;
+    protected $blob;
     protected $reasonData;
 
-    protected $job;
-
     public function __construct(array $literals, $reason, $reasonData, $job = null)
     {
         // sort all packages ascending by id
         sort($literals);
 
         $this->literals = $literals;
-        $this->reason = $reason;
         $this->reasonData = $reasonData;
 
-        $this->disabled = false;
-        $this->job = $job;
-        $this->type = -1;
+        if ($job) {
+            $this->job = $job;
+        }
 
+        $this->blob = pack('ccc', -1, $reason, false);
     }
 
     public function getHash()
@@ -64,24 +59,14 @@ class Rule
         return $data['hash'];
     }
 
-    public function setId($id)
-    {
-        $this->id = $id;
-    }
-
-    public function getId()
-    {
-        return $this->id;
-    }
-
     public function getJob()
     {
-        return $this->job;
+        return isset($this->job) ? $this->job : null;
     }
 
     public function getReason()
     {
-        return $this->reason;
+        return $this->getBlob('a2');
     }
 
     public function getReasonData()
@@ -91,11 +76,11 @@ class Rule
 
     public function getRequiredPackage()
     {
-        if ($this->reason === self::RULE_JOB_INSTALL) {
+        if ($this->getReason() === self::RULE_JOB_INSTALL) {
             return $this->reasonData;
         }
 
-        if ($this->reason === self::RULE_PACKAGE_REQUIRES) {
+        if ($this->getReason() === self::RULE_PACKAGE_REQUIRES) {
             return $this->reasonData->getTarget();
         }
     }
@@ -125,32 +110,32 @@ class Rule
 
     public function setType($type)
     {
-        $this->type = $type;
+        return $this->setBlob('a1', $type);
     }
 
     public function getType()
     {
-        return $this->type;
+        return $this->getBlob('a1');
     }
 
     public function disable()
     {
-        $this->disabled = true;
+        return $this->setBlob('a3', true);
     }
 
     public function enable()
     {
-        $this->disabled = false;
+        return $this->setBlob('a3', false);
     }
 
     public function isDisabled()
     {
-        return $this->disabled;
+        return (bool) $this->getBlob('a3');
     }
 
     public function isEnabled()
     {
-        return !$this->disabled;
+        return !$this->getBlob('a3');
     }
 
     /**
@@ -176,7 +161,7 @@ class Rule
             $ruleText .= $pool->literalToPrettyString($literal, $installedMap);
         }
 
-        switch ($this->reason) {
+        switch ($this->getReason()) {
             case self::RULE_INTERNAL_ALLOW_UPDATE:
                 return $ruleText;
 
@@ -268,6 +253,20 @@ class Rule
         return implode(', ', $prepared);
     }
 
+    private function getBlob($var)
+    {
+        $current = unpack('c3a', $this->blob);
+        return $current[$var];
+    }
+
+    private function setBlob($var, $value)
+    {
+        $current = unpack('c3a', $this->blob);
+        $current[$var] = $value;
+        array_unshift($current, 'ccc');
+        $this->blob = call_user_func_array('pack', $current);
+    }
+
     /**
      * Formats a rule as a string of the format (Literal1|Literal2|...)
      *

+ 0 - 1
src/Composer/DependencyResolver/RuleSet.php

@@ -66,7 +66,6 @@ class RuleSet implements \IteratorAggregate, \Countable
         $this->ruleById[$this->nextRuleId] = $rule;
         $rule->setType($type);
 
-        $rule->setId($this->nextRuleId);
         $this->nextRuleId++;
 
         $hash = $rule->getHash();

+ 3 - 3
src/Composer/DependencyResolver/Solver.php

@@ -319,7 +319,7 @@ class Solver
 
             $this->rules->add($newRule, RuleSet::TYPE_LEARNED);
 
-            $this->learnedWhy[$newRule->getId()] = $why;
+            $this->learnedWhy[spl_object_hash($newRule)] = $why;
 
             $ruleNode = new RuleWatchNode($newRule);
             $ruleNode->watch2OnHighest($this->decisions);
@@ -454,7 +454,7 @@ class Solver
 
     private function analyzeUnsolvableRule($problem, $conflictRule)
     {
-        $why = $conflictRule->getId();
+        $why = spl_object_hash($conflictRule);
 
         if ($conflictRule->getType() == RuleSet::TYPE_LEARNED) {
             $learnedWhy = $this->learnedWhy[$why];
@@ -572,7 +572,7 @@ class Solver
     private function enableDisableLearnedRules()
     {
         foreach ($this->rules->getIteratorFor(RuleSet::TYPE_LEARNED) as $rule) {
-            $why = $this->learnedWhy[$rule->getId()];
+            $why = $this->learnedWhy[spl_object_hash($rule)];
             $problemRules = $this->learnedPool[$why];
 
             $foundDisabled = false;

+ 3 - 10
tests/Composer/Test/DependencyResolver/RuleTest.php

@@ -13,6 +13,7 @@
 namespace Composer\Test\DependencyResolver;
 
 use Composer\DependencyResolver\Rule;
+use Composer\DependencyResolver\RuleSet;
 use Composer\DependencyResolver\Pool;
 use Composer\Repository\ArrayRepository;
 use Composer\TestCase;
@@ -34,14 +35,6 @@ class RuleTest extends TestCase
         $this->assertEquals($hash['hash'], $rule->getHash());
     }
 
-    public function testSetAndGetId()
-    {
-        $rule = new Rule(array(), 'job1', null);
-        $rule->setId(666);
-
-        $this->assertEquals(666, $rule->getId());
-    }
-
     public function testEqualsForRulesWithDifferentHashes()
     {
         $rule = new Rule(array(1, 2), 'job1', null);
@@ -69,9 +62,9 @@ class RuleTest extends TestCase
     public function testSetAndGetType()
     {
         $rule = new Rule(array(), 'job1', null);
-        $rule->setType('someType');
+        $rule->setType(RuleSet::TYPE_JOB);
 
-        $this->assertEquals('someType', $rule->getType());
+        $this->assertEquals(RuleSet::TYPE_JOB, $rule->getType());
     }
 
     public function testEnable()