From 8daf68e366fa9fa2794ae667f51562663856237c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 15 Feb 2014 13:38:39 +0100 Subject: propagate a negative score point along breaks/conflicts versioned -dev packages like db and boost have the problem of no dependencies which would give them a competitive advantage against an older incarnation of the -dev package, so they tend to be kept back until the old version is removed from the archive, which, if the user has older releases in its sources can take a long time (or never happens). The newer version has a conflicts/breaks against the older one, but the older one hasn't against the newer, so by giving via the conflicts the older one a reduced score the newer one can win if there is no other reason to keep it. If both have a conflict against each other the scoring will cancel itself out, so no harm done. This gives "action" a slightly bigger edge in breaks/conflicts cases than before, but holding back isn't a really good solution anyway. --- apt-pkg/algorithms.cc | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 0363ab3e2..db1ebd7e3 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -394,8 +394,18 @@ void pkgProblemResolver::MakeScores() }; int PrioEssentials = _config->FindI("pkgProblemResolver::Scores::Essentials",100); int PrioInstalledAndNotObsolete = _config->FindI("pkgProblemResolver::Scores::NotObsolete",1); - int PrioDepends = _config->FindI("pkgProblemResolver::Scores::Depends",1); - int PrioRecommends = _config->FindI("pkgProblemResolver::Scores::Recommends",1); + int DepMap[] = { + 0, + _config->FindI("pkgProblemResolver::Scores::Depends",1), + _config->FindI("pkgProblemResolver::Scores::PreDepends",1), + _config->FindI("pkgProblemResolver::Scores::Suggests",0), + _config->FindI("pkgProblemResolver::Scores::Recommends",1), + _config->FindI("pkgProblemResolver::Scores::Conflicts",-1), + _config->FindI("pkgProblemResolver::Scores::Replaces",0), + _config->FindI("pkgProblemResolver::Scores::Obsoletes",0), + _config->FindI("pkgProblemResolver::Scores::Breaks",-1), + _config->FindI("pkgProblemResolver::Scores::Enhances",0) + }; int AddProtected = _config->FindI("pkgProblemResolver::Scores::AddProtected",10000); int AddEssential = _config->FindI("pkgProblemResolver::Scores::AddEssential",5000); @@ -408,8 +418,15 @@ void pkgProblemResolver::MakeScores() << " Extra => " << PrioMap[pkgCache::State::Extra] << endl << " Essentials => " << PrioEssentials << endl << " InstalledAndNotObsolete => " << PrioInstalledAndNotObsolete << endl - << " Depends => " << PrioDepends << endl - << " Recommends => " << PrioRecommends << endl + << " Pre-Depends => " << DepMap[pkgCache::Dep::PreDepends] << endl + << " Depends => " << DepMap[pkgCache::Dep::Depends] << endl + << " Recommends => " << DepMap[pkgCache::Dep::Recommends] << endl + << " Suggests => " << DepMap[pkgCache::Dep::Suggests] << endl + << " Conflicts => " << DepMap[pkgCache::Dep::Conflicts] << endl + << " Breaks => " << DepMap[pkgCache::Dep::DpkgBreaks] << endl + << " Replaces => " << DepMap[pkgCache::Dep::Replaces] << endl + << " Obsoletes => " << DepMap[pkgCache::Dep::Obsoletes] << endl + << " Enhances => " << DepMap[pkgCache::Dep::Enhances] << endl << " AddProtected => " << AddProtected << endl << " AddEssential => " << AddEssential << endl; @@ -446,17 +463,11 @@ void pkgProblemResolver::MakeScores() { if (Cache[I].InstallVer == 0) continue; - + for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false; ++D) - { - if (D->Type == pkgCache::Dep::Depends || - D->Type == pkgCache::Dep::PreDepends) - Scores[D.TargetPkg()->ID] += PrioDepends; - else if (D->Type == pkgCache::Dep::Recommends) - Scores[D.TargetPkg()->ID] += PrioRecommends; - } - } - + Scores[D.TargetPkg()->ID] += DepMap[D->Type]; + } + // Copy the scores to advoid additive looping SPtrArray OldScores = new int[Size]; memcpy(OldScores,Scores,sizeof(*Scores)*Size); -- cgit v1.2.3 From cb4b85b0bdba6a0c43ca62259dcd35fccd38a45a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 15 Feb 2014 14:47:24 +0100 Subject: do not do the same looping twice Git-Dch: Ignore --- apt-pkg/algorithms.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index db1ebd7e3..4d86e5ff8 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -456,14 +456,8 @@ void pkgProblemResolver::MakeScores() */ if (I->CurrentVer != 0 && Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable()) Score += PrioInstalledAndNotObsolete; - } - - // Now that we have the base scores we go and propagate dependencies - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) - { - if (Cache[I].InstallVer == 0) - continue; + // propagate score points along dependencies for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false; ++D) Scores[D.TargetPkg()->ID] += DepMap[D->Type]; } -- cgit v1.2.3 From 9ec748ff103840c4c65471ca00d3b72984131ce4 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 23 Feb 2014 22:24:27 +0100 Subject: check version before adding scores in resolver Prevents that "old" dependencies have an influence in the scoring. With positive dependencies this is usually not a problem, but negative dependencies can linger around for a long time. --- apt-pkg/algorithms.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 4d86e5ff8..8320e7ef0 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -459,7 +459,18 @@ void pkgProblemResolver::MakeScores() // propagate score points along dependencies for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false; ++D) - Scores[D.TargetPkg()->ID] += DepMap[D->Type]; + { + if (DepMap[D->Type] == 0) + continue; + pkgCache::PkgIterator const T = D.TargetPkg(); + if (D->Version != 0) + { + pkgCache::VerIterator const IV = Cache[T].InstVerIter(Cache); + if (IV.end() == true || D.IsSatisfied(IV) != D.IsNegative()) + continue; + } + Scores[T->ID] += DepMap[D->Type]; + } } // Copy the scores to advoid additive looping -- cgit v1.2.3 From e788a834ce421042e727b72e43177edaa47e53a7 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 27 Feb 2014 02:18:11 +0100 Subject: warning: useless cast to type A [-Wuseless-cast] Git-Dch: Ignore Reported-By: gcc -Wuseless-cast --- apt-pkg/algorithms.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 8320e7ef0..2e167119d 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -885,8 +885,8 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) } if (Debug == true) - clog << " Considering " << Pkg.FullName(false) << ' ' << (int)Scores[Pkg->ID] << - " as a solution to " << I.FullName(false) << ' ' << (int)Scores[I->ID] << endl; + clog << " Considering " << Pkg.FullName(false) << ' ' << Scores[Pkg->ID] << + " as a solution to " << I.FullName(false) << ' ' << Scores[I->ID] << endl; /* Try to fix the package under consideration rather than fiddle with the VList package */ -- cgit v1.2.3 From 453b82a388013e522b3a1b9fcd6ed0810dab1f4f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 5 Mar 2014 22:11:25 +0100 Subject: cleanup headers and especially #includes everywhere Beside being a bit cleaner it hopefully also resolves oddball problems I have with high levels of parallel jobs. Git-Dch: Ignore Reported-By: iwyu (include-what-you-use) --- apt-pkg/algorithms.cc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 2e167119d..a7b676660 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -19,19 +19,18 @@ #include #include #include -#include #include -#include #include -#include -#include #include +#include +#include +#include +#include -#include +#include +#include #include -#include #include -#include #include /*}}}*/ -- cgit v1.2.3 From 4cd4a2e7033a2af214be1d830b56fab719088b7a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 11 Apr 2014 13:33:31 +0200 Subject: consider priorities only for downloadable pkgs in resolver A package which can't be downloaded anymore is very likely dropped from a release and can therefore no longer be 'standard' (or similar). We therefore do not grant points for them anymore and demote them to prio:extra instead which helps other packages breaking them away even if they have a lower priority. The testcase was initially created by Michael Vogt and just amended. --- apt-pkg/algorithms.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index a7b676660..608ec7fce 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -445,19 +445,22 @@ void pkgProblemResolver::MakeScores() || (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) Score += PrioEssentials; - // We transform the priority - if (Cache[I].InstVerIter(Cache)->Priority <= 5) - Score += PrioMap[Cache[I].InstVerIter(Cache)->Priority]; - + pkgCache::VerIterator const InstVer = Cache[I].InstVerIter(Cache); + // We apply priorities only to downloadable packages, all others are prio:extra + // as an obsolete prio:standard package can't be that standard anymore… + if (InstVer->Priority <= pkgCache::State::Extra && InstVer.Downloadable() == true) + Score += PrioMap[InstVer->Priority]; + else + Score += PrioMap[pkgCache::State::Extra]; + /* This helps to fix oddball problems with conflicting packages - on the same level. We enhance the score of installed packages - if those are not obsolete - */ + on the same level. We enhance the score of installed packages + if those are not obsolete */ if (I->CurrentVer != 0 && Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable()) Score += PrioInstalledAndNotObsolete; // propagate score points along dependencies - for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false; ++D) + for (pkgCache::DepIterator D = InstVer.DependsList(); D.end() == false; ++D) { if (DepMap[D->Type] == 0) continue; -- cgit v1.2.3