1
0
Fork 0

Use an SplFixedArray for the solver's decision map

pull/9/head
Nils Adermann 2011-08-21 07:30:10 -04:00
parent b1d16a88b7
commit 4dbb73daba
2 changed files with 33 additions and 27 deletions

View File

@ -56,6 +56,16 @@ class Pool
return $this->packages[$id - 1]; return $this->packages[$id - 1];
} }
/**
* Retrieves the highest id assigned to a package in this pool
*
* @return int Highest package id
*/
public function getMaxId()
{
return count($this->packages);
}
/** /**
* Searches all packages providing the given package name and match the constraint * Searches all packages providing the given package name and match the constraint
* *

View File

@ -48,6 +48,7 @@ class Solver
protected $noObsoletes = array(); protected $noObsoletes = array();
protected $watches = array(); protected $watches = array();
protected $removeWatches = array(); protected $removeWatches = array();
protected $decisionMap;
protected $packageToUpdateRule = array(); protected $packageToUpdateRule = array();
protected $packageToFeatureRule = array(); protected $packageToFeatureRule = array();
@ -429,11 +430,7 @@ class Solver
$watchLevel = 0; $watchLevel = 0;
foreach ($literals as $literal) { foreach ($literals as $literal) {
if (isset($this->decisionMap[$literal->getPackageId()])) { $level = abs($this->decisionMap[$literal->getPackageId()]);
$level = abs($this->decisionMap[$literal->getPackageId()]);
} else {
$level = 0;
}
if ($level > $watchLevel) { if ($level > $watchLevel) {
$rule->watch2 = $literal->getId(); $rule->watch2 = $literal->getId();
@ -538,7 +535,7 @@ class Solver
$decisionLiteral = array_pop($this->decisionQueue); $decisionLiteral = array_pop($this->decisionQueue);
array_pop($this->decisionQueueWhy); array_pop($this->decisionQueueWhy);
unset($this->decisionQueueFree[count($this->decisionQueue)]); unset($this->decisionQueueFree[count($this->decisionQueue)]);
unset($this->decisionMap[$decisionLiteral->getPackageId()]); $this->decisionMap[$decisionLiteral->getPackageId()] = 0;
} }
$ruleIndex = -1; $ruleIndex = -1;
} }
@ -551,7 +548,7 @@ class Solver
$literals = $rule->getLiterals(); $literals = $rule->getLiterals();
$literal = $literals[0]; $literal = $literals[0];
if (!isset($this->decisionMap[$literal->getPackageId()])) { if ($this->decisionMap[$literal->getPackageId()] == 0) {
$this->decisionQueue[] = $literal; $this->decisionQueue[] = $literal;
$this->decisionQueueWhy[] = $rule; $this->decisionQueueWhy[] = $rule;
$this->addDecision($literal, 1); $this->addDecision($literal, 1);
@ -936,6 +933,8 @@ class Solver
$this->jobs = $request->getJobs(); $this->jobs = $request->getJobs();
$installedPackages = $this->installed->getPackages(); $installedPackages = $this->installed->getPackages();
$this->decisionMap = new \SplFixedArray($this->pool->getMaxId() + 1);
foreach ($this->jobs as $job) { foreach ($this->jobs as $job) {
switch ($job['cmd']) { switch ($job['cmd']) {
case 'update-all': case 'update-all':
@ -1139,7 +1138,6 @@ class Solver
protected $decisionQueueWhy = array(); protected $decisionQueueWhy = array();
protected $decisionQueueFree = array(); protected $decisionQueueFree = array();
protected $propagateIndex; protected $propagateIndex;
protected $decisionMap = array();
protected $branches = array(); protected $branches = array();
protected $problems = array(); protected $problems = array();
protected $learnedPool = array(); protected $learnedPool = array();
@ -1172,60 +1170,60 @@ class Solver
protected function decisionsContain(Literal $l) protected function decisionsContain(Literal $l)
{ {
return (isset($this->decisionMap[$l->getPackageId()]) && ( return (
$this->decisionMap[$l->getPackageId()] > 0 && $l->isWanted() || $this->decisionMap[$l->getPackageId()] > 0 && $l->isWanted() ||
$this->decisionMap[$l->getPackageId()] < 0 && !$l->isWanted() $this->decisionMap[$l->getPackageId()] < 0 && !$l->isWanted()
)); );
} }
protected function decisionsContainId($literalId) protected function decisionsContainId($literalId)
{ {
$packageId = abs($literalId); $packageId = abs($literalId);
return (isset($this->decisionMap[$packageId]) && ( return (
$this->decisionMap[$packageId] > 0 && $literalId > 0 || $this->decisionMap[$packageId] > 0 && $literalId > 0 ||
$this->decisionMap[$packageId] < 0 && $literalId < 0 $this->decisionMap[$packageId] < 0 && $literalId < 0
)); );
} }
protected function decisionsSatisfy(Literal $l) protected function decisionsSatisfy(Literal $l)
{ {
return ($l->isWanted() && isset($this->decisionMap[$l->getPackageId()]) && $this->decisionMap[$l->getPackageId()] > 0) || return ($l->isWanted() && $this->decisionMap[$l->getPackageId()] > 0) ||
(!$l->isWanted() && (!isset($this->decisionMap[$l->getPackageId()]) || $this->decisionMap[$l->getPackageId()] < 0)); (!$l->isWanted() && $this->decisionMap[$l->getPackageId()] <= 0);
} }
protected function decisionsConflict(Literal $l) protected function decisionsConflict(Literal $l)
{ {
return (isset($this->decisionMap[$l->getPackageId()]) && ( return (
$this->decisionMap[$l->getPackageId()] > 0 && !$l->isWanted() || $this->decisionMap[$l->getPackageId()] > 0 && !$l->isWanted() ||
$this->decisionMap[$l->getPackageId()] < 0 && $l->isWanted() $this->decisionMap[$l->getPackageId()] < 0 && $l->isWanted()
)); );
} }
protected function decisionsConflictId($literalId) protected function decisionsConflictId($literalId)
{ {
$packageId = abs($literalId); $packageId = abs($literalId);
return (isset($this->decisionMap[$packageId]) && ( return (
$this->decisionMap[$packageId] > 0 && !($literalId < 0) || $this->decisionMap[$packageId] > 0 && !($literalId < 0) ||
$this->decisionMap[$packageId] < 0 && $literalId > 0 $this->decisionMap[$packageId] < 0 && $literalId > 0
)); );
} }
protected function decided(PackageInterface $p) protected function decided(PackageInterface $p)
{ {
return isset($this->decisionMap[$p->getId()]); return $this->decisionMap[$p->getId()] != 0;
} }
protected function undecided(PackageInterface $p) protected function undecided(PackageInterface $p)
{ {
return !isset($this->decisionMap[$p->getId()]); return $this->decisionMap[$p->getId()] == 0;
} }
protected function decidedInstall(PackageInterface $p) { protected function decidedInstall(PackageInterface $p) {
return isset($this->decisionMap[$p->getId()]) && $this->decisionMap[$p->getId()] > 0; return $this->decisionMap[$p->getId()] > 0;
} }
protected function decidedRemove(PackageInterface $p) { protected function decidedRemove(PackageInterface $p) {
return isset($this->decisionMap[$p->getId()]) && $this->decisionMap[$p->getId()] < 0; return $this->decisionMap[$p->getId()] < 0;
} }
/** /**
@ -1311,7 +1309,7 @@ class Solver
while (!empty($this->decisionQueue)) { while (!empty($this->decisionQueue)) {
$literal = $this->decisionQueue[count($this->decisionQueue) - 1]; $literal = $this->decisionQueue[count($this->decisionQueue) - 1];
if (!isset($this->decisionMap[$literal->getPackageId()])) { if (!$this->decisionMap[$literal->getPackageId()]) {
break; break;
} }
@ -1326,7 +1324,7 @@ class Solver
* solv->recommendations.count--; * solv->recommendations.count--;
*/ */
unset($this->decisionMap[$literal->getPackageId()]); $this->decisionMap[$literal->getPackageId()] = 0;
array_pop($this->decisionQueue); array_pop($this->decisionQueue);
array_pop($this->decisionQueueWhy); array_pop($this->decisionQueueWhy);
@ -1672,9 +1670,7 @@ class Solver
private function resetSolver() private function resetSolver()
{ {
while ($literal = array_pop($this->decisionQueue)) { while ($literal = array_pop($this->decisionQueue)) {
if (isset($this->decisionMap[$literal->getPackageId()])) { $this->decisionMap[$literal->getPackageId()] = 0;
unset($this->decisionMap[$literal->getPackageId()]);
}
} }
$this->decisionQueueWhy = array(); $this->decisionQueueWhy = array();