From a0c19a217ca2ed38ae0ecb4b8d2d4f8c4e53289f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 12 Jul 2015 13:41:12 +0200 Subject: implement a more generic ShowList method apt-get is displaying various lists of package names, which until now it was building as a string before passing it to ShowList, which inserted linebreaks at fitting points and showed a title if needed, but it never really understood what it was working with. With the help of C++11 the new generic knows not only what it works with, but generates the list on the fly rather than asking for it and potentially discarding parts of the input (= the non-default verbose display). It also doubles as a test for how usable the CacheSets are with C++11. (Not all callers are adapted yet.) Git-Dch: Ignore --- apt-private/private-cachefile.cc | 61 ++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 30 deletions(-) (limited to 'apt-private/private-cachefile.cc') diff --git a/apt-private/private-cachefile.cc b/apt-private/private-cachefile.cc index 29e665245..2b2050684 100644 --- a/apt-private/private-cachefile.cc +++ b/apt-private/private-cachefile.cc @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include @@ -21,39 +21,40 @@ using namespace std; -// CacheFile::NameComp - QSort compare by name /*{{{*/ -// --------------------------------------------------------------------- -/* */ -pkgCache *CacheFile::SortCache = 0; -int CacheFile::NameComp(const void *a,const void *b) +static bool SortPackagesByName(pkgCache * const Owner, + map_pointer_t const A, map_pointer_t const B) { - if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0) - return *(pkgCache::Package **)a - *(pkgCache::Package **)b; - - const pkgCache::Package &A = **(pkgCache::Package **)a; - const pkgCache::Package &B = **(pkgCache::Package **)b; - const pkgCache::Group * const GA = SortCache->GrpP + A.Group; - const pkgCache::Group * const GB = SortCache->GrpP + B.Group; - - return strcmp(SortCache->StrP + GA->Name,SortCache->StrP + GB->Name); + if (A == 0) + return false; + if (B == 0 || A == B) + return true; + pkgCache::Group const * const GA = Owner->GrpP + A; + pkgCache::Group const * const GB = Owner->GrpP + B; + return strcmp(Owner->StrP + GA->Name, Owner->StrP + GB->Name) <= 0; } - /*}}}*/ -// CacheFile::Sort - Sort by name /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void CacheFile::Sort() +SortedPackageUniverse::SortedPackageUniverse(CacheFile &Cache) : + PackageUniverse{Cache}, List{Cache.UniverseList} { - delete [] List; - List = new pkgCache::Package *[Cache->Head().PackageCount]; - memset(List,0,sizeof(*List)*Cache->Head().PackageCount); - pkgCache::PkgIterator I = Cache->PkgBegin(); - for (;I.end() != true; ++I) - List[I->ID] = I; - - SortCache = *this; - qsort(List,Cache->Head().PackageCount,sizeof(*List),NameComp); } - /*}}}*/ +void SortedPackageUniverse::LazyInit() const +{ + if (List.empty() == false) + return; + pkgCache * const Owner = data(); + // In Multi-Arch systems Grps are easier to sort than Pkgs + std::vector GrpList; + List.reserve(Owner->Head().GroupCount); + for (pkgCache::GrpIterator I{Owner->GrpBegin()}; I.end() != true; ++I) + GrpList.emplace_back(I - Owner->GrpP); + std::stable_sort(GrpList.begin(), GrpList.end(), std::bind( &SortPackagesByName, Owner, std::placeholders::_1, std::placeholders::_2 )); + List.reserve(Owner->Head().PackageCount); + for (auto G : GrpList) + { + pkgCache::GrpIterator const Grp(*Owner, Owner->GrpP + G); + for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() != true; P = Grp.NextPkg(P)) + List.emplace_back(P - Owner->PkgP); + } +} // CacheFile::CheckDeps - Open the cache file /*{{{*/ // --------------------------------------------------------------------- /* This routine generates the caches and then opens the dependency cache -- cgit v1.2.3