summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/depcache.cc181
-rw-r--r--apt-pkg/depcache.h25
2 files changed, 93 insertions, 113 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index dfd1e1084..8ab156220 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -125,7 +125,6 @@ int pkgDepCache::DecreaseActionGroupLevel()
struct pkgDepCache::Private
{
std::unique_ptr<InRootSetFunc> inRootSetFunc;
- std::vector<bool> fullyExplored;
std::unique_ptr<APT::CacheFilter::Matcher> IsAVersionedKernelPackage, IsProtectedKernelPackage;
};
pkgDepCache::pkgDepCache(pkgCache *const pCache, Policy *const Plcy) : group_level(0), Cache(pCache), PkgState(0), DepState(0),
@@ -2201,18 +2200,17 @@ pkgDepCache::InRootSetFunc *pkgDepCache::GetCachedRootSetFunc()
return d->inRootSetFunc.get();
}
/*}}}*/
-bool pkgDepCache::MarkFollowsRecommends()
+bool pkgDepCache::MarkFollowsRecommends() /*{{{*/
{
return _config->FindB("APT::AutoRemove::RecommendsImportant", true);
}
-
-bool pkgDepCache::MarkFollowsSuggests()
+ /*}}}*/
+bool pkgDepCache::MarkFollowsSuggests() /*{{{*/
{
return _config->FindB("APT::AutoRemove::SuggestsImportant", true);
}
-
-// pkgDepCache::MarkRequired - the main mark algorithm /*{{{*/
-static bool IsPkgInBoringState(pkgCache::PkgIterator const &Pkg, pkgDepCache::StateCache const * const PkgState)
+ /*}}}*/
+static bool IsPkgInBoringState(pkgCache::PkgIterator const &Pkg, pkgDepCache::StateCache const * const PkgState)/*{{{*/
{
if (Pkg->CurrentVer == 0)
{
@@ -2226,81 +2224,31 @@ static bool IsPkgInBoringState(pkgCache::PkgIterator const &Pkg, pkgDepCache::St
}
return false;
}
-bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
-{
- if (_config->Find("APT::Solver", "internal") != "internal")
- return true;
-
- bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
-
- // init the states
- auto const PackagesCount = Head().PackageCount;
- for(auto i = decltype(PackagesCount){0}; i < PackagesCount; ++i)
- {
- PkgState[i].Marked = false;
- PkgState[i].Garbage = false;
- }
- d->fullyExplored = std::vector<bool>(PackagesCount, false);
- if (debug_autoremove)
- for(PkgIterator p = PkgBegin(); !p.end(); ++p)
- if(PkgState[p->ID].Flags & Flag::Auto)
- std::clog << "AutoDep: " << p.FullName() << std::endl;
-
- bool const follow_recommends = MarkFollowsRecommends();
- bool const follow_suggests = MarkFollowsSuggests();
-
- // do the mark part, this is the core bit of the algorithm
- for (PkgIterator P = PkgBegin(); !P.end(); ++P)
- {
- if (PkgState[P->ID].Marked || IsPkgInBoringState(P, PkgState))
- continue;
-
- const char *reason = nullptr;
-
- if ((PkgState[P->ID].Flags & Flag::Auto) == 0)
- reason = "Manual-Installed";
- else if (P->Flags & Flag::Essential)
- reason = "Essential";
- else if (P->Flags & Flag::Important)
- reason = "Important";
- else if (P->CurrentVer != 0 && P.CurrentVer()->Priority == pkgCache::State::Required)
- reason = "Required";
- else if (userFunc.InRootSet(P))
- reason = "Blacklisted [APT::NeverAutoRemove]";
- else if (not IsModeChangeOk(*this, ModeGarbage, P, 0, false, DebugMarker))
- reason = "Hold";
- else
- continue;
-
- if (PkgState[P->ID].Install())
- MarkPackage(P, PkgState[P->ID].InstVerIter(*this),
- follow_recommends, follow_suggests, reason);
- else
- MarkPackage(P, P.CurrentVer(),
- follow_recommends, follow_suggests, reason);
- }
- d->fullyExplored.clear();
- return true;
-}
/*}}}*/
// MarkPackage - mark a single package in Mark-and-Sweep /*{{{*/
-void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &Pkg,
- const pkgCache::VerIterator &Ver,
- bool const &follow_recommends,
- bool const &follow_suggests,
- const char *reason)
+static void MarkPackage(pkgCache::PkgIterator const &Pkg,
+ pkgCache::VerIterator const &Ver,
+ bool const follow_recommends,
+ bool const follow_suggests,
+ bool const debug_autoremove,
+ std::string_view const reason,
+ pkgCache &Cache,
+ pkgDepCache &DepCache,
+ pkgDepCache::StateCache *const PkgState,
+ std::vector<bool> &fullyExplored,
+ std::unique_ptr<APT::CacheFilter::Matcher> &IsAVersionedKernelPackage,
+ std::unique_ptr<APT::CacheFilter::Matcher> &IsProtectedKernelPackage)
{
- if (Ver.end() || (d->fullyExplored[Pkg->ID] && PkgState[Pkg->ID].Marked))
+ if (Ver.end() || (fullyExplored[Pkg->ID] && PkgState[Pkg->ID].Marked))
return;
if (IsPkgInBoringState(Pkg, PkgState))
{
- d->fullyExplored[Pkg->ID] = true;
+ fullyExplored[Pkg->ID] = true;
return;
}
PkgState[Pkg->ID].Marked = true;
- bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove", false);
if(debug_autoremove)
std::clog << "Marking: " << Pkg.FullName() << " " << Ver.VerStr()
<< " (" << reason << ")" << std::endl;
@@ -2315,13 +2263,13 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &Pkg,
for (auto D = Ver.DependsList(); not D.end(); ++D)
{
auto const T = D.TargetPkg();
- if (T.end() || d->fullyExplored[T->ID])
+ if (T.end() || fullyExplored[T->ID])
continue;
- if (D->Type != Dep::Depends &&
- D->Type != Dep::PreDepends &&
- (follow_recommends == false || D->Type != Dep::Recommends) &&
- (follow_suggests == false || D->Type != Dep::Suggests))
+ if (D->Type != pkgCache::Dep::Depends &&
+ D->Type != pkgCache::Dep::PreDepends &&
+ (not follow_recommends || D->Type != pkgCache::Dep::Recommends) &&
+ (not follow_suggests || D->Type != pkgCache::Dep::Suggests))
continue;
bool unsatisfied_choice = false;
@@ -2329,7 +2277,7 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &Pkg,
// collect real part
if (not IsPkgInBoringState(T, PkgState))
{
- auto const TV = (PkgState[T->ID].Install()) ? PkgState[T->ID].InstVerIter(*this) : T.CurrentVer();
+ auto const TV = (PkgState[T->ID].Install()) ? PkgState[T->ID].InstVerIter(DepCache) : T.CurrentVer();
if (likely(not TV.end()))
{
if (not D.IsSatisfied(TV))
@@ -2349,7 +2297,7 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &Pkg,
// we want to ignore provides from uninteresting versions
auto const PV = (PkgState[PP->ID].Install()) ?
- PkgState[PP->ID].InstVerIter(*this) : PP.CurrentVer();
+ PkgState[PP->ID].InstVerIter(DepCache) : PP.CurrentVer();
if (unlikely(PV.end()) || PV != Prv.OwnerVer())
continue;
@@ -2366,8 +2314,8 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &Pkg,
// if the provider is a versioned kernel package mark them only for protected kernels
if (providers.second.size() == 1)
continue;
- if (not d->IsAVersionedKernelPackage)
- d->IsAVersionedKernelPackage = [&]() -> std::unique_ptr<APT::CacheFilter::Matcher> {
+ if (not IsAVersionedKernelPackage)
+ IsAVersionedKernelPackage = [&]() -> std::unique_ptr<APT::CacheFilter::Matcher> {
auto const patterns = _config->FindVector("APT::VersionedKernelPackages");
if (patterns.empty())
return std::make_unique<APT::CacheFilter::FalseMatcher>();
@@ -2377,35 +2325,92 @@ void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &Pkg,
regex << patterns.back() << "-.*$";
return std::make_unique<APT::CacheFilter::PackageNameMatchesRegEx>(regex.str());
}();
- if (not std::all_of(providers.second.begin(), providers.second.end(), [&](auto const &Prv) { return (*d->IsAVersionedKernelPackage)(Prv.ParentPkg()); }))
+ if (not std::all_of(providers.second.begin(), providers.second.end(), [&](auto const &Prv) { return (*IsAVersionedKernelPackage)(Prv.ParentPkg()); }))
continue;
// … if there is at least one for protected kernels installed
- if (not d->IsProtectedKernelPackage)
- d->IsProtectedKernelPackage = APT::KernelAutoRemoveHelper::GetProtectedKernelsFilter(Cache);
- if (not std::any_of(providers.second.begin(), providers.second.end(), [&](auto const &Prv) { return (*d->IsProtectedKernelPackage)(Prv.ParentPkg()); }))
+ if (not IsProtectedKernelPackage)
+ IsProtectedKernelPackage = APT::KernelAutoRemoveHelper::GetProtectedKernelsFilter(&Cache);
+ if (not std::any_of(providers.second.begin(), providers.second.end(), [&](auto const &Prv) { return (*IsProtectedKernelPackage)(Prv.ParentPkg()); }))
continue;
providers.second.erase(std::remove_if(providers.second.begin(), providers.second.end(),
- [&](auto const &Prv) { return not((*d->IsProtectedKernelPackage)(Prv.ParentPkg())); }),
+ [&](auto const &Prv) { return not((*IsProtectedKernelPackage)(Prv.ParentPkg())); }),
providers.second.end());
}
if (not unsatisfied_choice)
- d->fullyExplored[T->ID] = true;
+ fullyExplored[T->ID] = true;
for (auto const &providers : providers_by_source)
{
for (auto const &PV : providers.second)
{
auto const PP = PV.ParentPkg();
if (debug_autoremove)
- std::clog << "Following dep: " << APT::PrettyDep(this, D)
+ std::clog << "Following dep: " << APT::PrettyDep(&DepCache, D)
<< ", provided by " << PP.FullName() << " " << PV.VerStr()
<< " (" << providers_by_source.size() << "/" << providers.second.size() << ")\n";
- MarkPackage(PP, PV, follow_recommends, follow_suggests, "Dependency");
+ MarkPackage(PP, PV, follow_recommends, follow_suggests, debug_autoremove,
+ "Dependency", Cache, DepCache, PkgState, fullyExplored,
+ IsAVersionedKernelPackage, IsProtectedKernelPackage);
}
}
}
}
/*}}}*/
+// pkgDepCache::MarkRequired - the main mark algorithm /*{{{*/
+bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
+{
+ if (_config->Find("APT::Solver", "internal") != "internal")
+ return true;
+
+ // init the states
+ auto const PackagesCount = Head().PackageCount;
+ for(auto i = decltype(PackagesCount){0}; i < PackagesCount; ++i)
+ {
+ PkgState[i].Marked = false;
+ PkgState[i].Garbage = false;
+ }
+ std::vector<bool> fullyExplored(PackagesCount, false);
+
+ bool const debug_autoremove = _config->FindB("Debug::pkgAutoRemove", false);
+ if (debug_autoremove)
+ for(PkgIterator p = PkgBegin(); !p.end(); ++p)
+ if(PkgState[p->ID].Flags & Flag::Auto)
+ std::clog << "AutoDep: " << p.FullName() << std::endl;
+
+ bool const follow_recommends = MarkFollowsRecommends();
+ bool const follow_suggests = MarkFollowsSuggests();
+
+ // do the mark part, this is the core bit of the algorithm
+ for (PkgIterator P = PkgBegin(); !P.end(); ++P)
+ {
+ if (PkgState[P->ID].Marked || IsPkgInBoringState(P, PkgState))
+ continue;
+
+ std::string_view reason;
+ if ((PkgState[P->ID].Flags & Flag::Auto) == 0)
+ reason = "Manual-Installed";
+ else if (P->Flags & Flag::Essential)
+ reason = "Essential";
+ else if (P->Flags & Flag::Important)
+ reason = "Important";
+ else if (P->CurrentVer != 0 && P.CurrentVer()->Priority == pkgCache::State::Required)
+ reason = "Required";
+ else if (userFunc.InRootSet(P))
+ reason = "Blacklisted [APT::NeverAutoRemove]";
+ else if (not IsModeChangeOk(*this, ModeGarbage, P, 0, false, DebugMarker))
+ reason = "Hold";
+ else
+ continue;
+
+ pkgCache::VerIterator const PV = (PkgState[P->ID].Install()) ? PkgState[P->ID].InstVerIter(*this) : P.CurrentVer();
+ MarkPackage(P, PV, follow_recommends, follow_suggests, debug_autoremove,
+ reason, *Cache, *this, PkgState, fullyExplored,
+ d->IsAVersionedKernelPackage, d->IsProtectedKernelPackage);
+ return false;
+ }
+ return true;
+}
+ /*}}}*/
bool pkgDepCache::Sweep() /*{{{*/
{
bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h
index e0c5c4069..be27b1d77 100644
--- a/apt-pkg/depcache.h
+++ b/apt-pkg/depcache.h
@@ -71,31 +71,6 @@ class APT_PUBLIC pkgDepCache : protected pkgCache::Namespace
};
private:
- /** \brief Mark a single package and all its unmarked important
- * dependencies during mark-and-sweep.
- *
- * Recursively invokes itself to mark all dependencies of the
- * package.
- *
- * \param pkg The package to mark.
- *
- * \param ver The version of the package that is to be marked.
- *
- * \param follow_recommends If \b true, recommendations of the
- * package will be recursively marked.
- *
- * \param follow_suggests If \b true, suggestions of the package
- * will be recursively marked.
- *
- * \param reason The reason why the package is being marked.
- * (Used in logging when Debug::pkgAutoRemove is set.)
- */
- APT_HIDDEN void MarkPackage(const pkgCache::PkgIterator &pkg,
- const pkgCache::VerIterator &ver,
- bool const &follow_recommends,
- bool const &follow_suggests,
- const char *reason);
-
/** \brief Update the Marked field of all packages.
*
* Each package's StateCache::Marked field will be set to \b true