From cfd0172fb0eeb15b2e2427c0e11b2ec65f501839 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 19 Jun 2020 13:58:35 +0200 Subject: Filter out impossible solutions for protected propagation If the package providing the given solution is tagged already for removal (or at least for "not installing") we can ignore this solution as a possibility as it is not one, which means we can avoid exploring the option and potentially forward the protected flag further if that helps in reducing the possibilities to a single one. --- apt-pkg/depcache.cc | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 7a068da1b..817d9de3c 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1278,10 +1278,23 @@ static APT::VersionVector getAllPossibleSolutions(pkgDepCache &Cache, pkgCache:: toNewInstall.emplace_back(std::move(Ver)); } } while (Start++ != End); - std::move(toNewInstall.begin(), toNewInstall.end(), std::back_inserter(toUpgrade)); + if (toUpgrade.empty()) + toUpgrade = std::move(toNewInstall); + else + std::move(toNewInstall.begin(), toNewInstall.end(), std::back_inserter(toUpgrade)); + if (not sorted) std::sort(toUpgrade.begin(), toUpgrade.end(), [](pkgCache::VerIterator const &A, pkgCache::VerIterator const &B) { return A->ID < B->ID; }); toUpgrade.erase(std::unique(toUpgrade.begin(), toUpgrade.end()), toUpgrade.end()); + + if (not End.IsNegative()) + toUpgrade.erase(std::remove_if(toUpgrade.begin(), toUpgrade.end(), [&Cache](pkgCache::VerIterator const &V) { + auto const P = V.ParentPkg(); + auto const &State = Cache[P]; + return State.Protect() && (State.Delete() || (State.Keep() && P->CurrentVer == 0)); + }), + toUpgrade.end()); + return toUpgrade; } /*}}}*/ @@ -1521,10 +1534,12 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg, bool AutoInst, unsigned long Depth, bool FromUser, bool ForceImportantDeps) { - if (not IsModeChangeOk(*this, ModeInstall, Pkg, Depth, FromUser, DebugMarker)) + StateCache &P = PkgState[Pkg->ID]; + if (P.Protect() && P.Keep() && P.CandidateVer != nullptr && P.CandidateVer == Pkg.CurrentVer()) + ; // we are here to mark our dependencies as protected, no state is changed + else if (not IsModeChangeOk(*this, ModeInstall, Pkg, Depth, FromUser, DebugMarker)) return false; - StateCache &P = PkgState[Pkg->ID]; // See if there is even any possible installation candidate if (P.CandidateVer == 0) -- cgit v1.2.3