summaryrefslogtreecommitdiff
path: root/apt-pkg/solver3.cc
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/solver3.cc')
-rw-r--r--apt-pkg/solver3.cc74
1 files changed, 33 insertions, 41 deletions
diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc
index ce38d75d8..a00da5716 100644
--- a/apt-pkg/solver3.cc
+++ b/apt-pkg/solver3.cc
@@ -357,52 +357,44 @@ bool APT::Solver::Enqueue(Var var, bool decision, Var reason)
return true;
}
-bool APT::Solver::Install(pkgCache::PkgIterator Pkg, Var reason, Group group)
+bool APT::Solver::PropagateInstall(Var var)
{
- if ((*this)[Pkg].decision == Decision::MUST)
- return true;
-
- // Note decision
- if (not Enqueue(Var(Pkg), true, reason))
- return false;
-
- bool anyInstallable = false;
- // Insert the work item.
- Work workItem{Var(Pkg), depth(), group};
- for (auto ver = Pkg.VersionList(); not ver.end(); ver++)
- {
- workItem.solutions.push_back(ver);
- if ((*this)[ver].decision != Decision::MUSTNOT)
- anyInstallable = true;
- }
-
- if (not anyInstallable)
+ if (auto Pkg = var.Pkg(cache); not Pkg.end())
{
- _error->Error("Conflict: %s -> %s but no versions are installable",
- WhyStr(reason).c_str(), Pkg.FullName().c_str());
+ bool anyInstallable = false;
+ bool anyMust = false;
+ // Insert the work item.
+ Work workItem{Var(Pkg), depth(), Group::SelectVersion};
for (auto ver = Pkg.VersionList(); not ver.end(); ver++)
- _error->Error("Uninstallable version: %s", WhyStr(Var(ver)).c_str());
- return false;
- }
-
- std::stable_sort(workItem.solutions.begin(), workItem.solutions.end(), CompareProviders3{cache, policy, Pkg, *this});
- assert(workItem.solutions.size() > 0);
+ {
+ workItem.solutions.push_back(ver);
+ if ((*this)[ver].decision != Decision::MUSTNOT)
+ anyInstallable = true;
+ if ((*this)[ver].decision == Decision::MUST)
+ anyMust = true;
+ }
- if (workItem.solutions.size() > 1 || workItem.optional)
- AddWork(std::move(workItem));
- else if (not Enqueue(Var(pkgCache::VerIterator(cache, workItem.solutions[0])), true, workItem.reason))
- return false;
+ if (not anyInstallable)
+ {
+ _error->Error("Conflict: %s -> %s but no versions are installable",
+ WhyStr((*this)[Pkg].reason).c_str(), Pkg.FullName().c_str());
+ for (auto ver = Pkg.VersionList(); not ver.end(); ver++)
+ _error->Error("Uninstallable version: %s", WhyStr(Var(ver)).c_str());
+ return false;
+ }
- if (not EnqueueCommonDependencies(Pkg))
- return false;
+ std::stable_sort(workItem.solutions.begin(), workItem.solutions.end(), CompareProviders3{cache, policy, Pkg, *this});
+ assert(workItem.solutions.size() > 0);
- return true;
-}
+ if (workItem.solutions.size() > 1 || workItem.optional)
+ AddWork(std::move(workItem));
+ else if (not Enqueue(Var(pkgCache::VerIterator(cache, workItem.solutions[0])), true, workItem.reason))
+ return false;
-bool APT::Solver::PropagateInstall(Var var)
-{
- if (auto Pkg = var.Pkg(cache); not Pkg.end())
- {
+ // FIXME: We skip enqueuing duplicate common dependencies if we already selected a version, but
+ // we should not have common dependencies duplicated in the version objects anyway.
+ if (not anyMust && not EnqueueCommonDependencies(Pkg))
+ return false;
}
else if (auto Ver = var.Ver(cache); not Ver.end())
{
@@ -897,7 +889,7 @@ bool APT::Solver::Solve()
}
if (unlikely(debug >= 3))
std::cerr << "(try it: " << ver.ParentPkg().FullName() << "=" << ver.VerStr() << ")\n";
- if (not Enqueue(Var(pkgCache::VerIterator(cache, ver)), true, item.reason) && not Pop())
+ if (not Enqueue(Var(ver), true, item.reason) && not Pop())
return false;
foundSolution = true;
break;
@@ -987,7 +979,7 @@ bool APT::Solver::FromDepCache(pkgDepCache &depcache)
if (not isOptional)
{
// Pre-empt the non-optional requests, as we don't want to queue them, we can just "unit propagate" here.
- if (depcache[P].Keep() ? not Install(P, {}, Group) : not Enqueue(Var(depcache.GetCandidateVersion(P)), true, {}))
+ if (depcache[P].Keep() ? not Enqueue(Var(P), true, {}) : not Enqueue(Var(depcache.GetCandidateVersion(P)), true, {}))
return false;
}
else