summaryrefslogtreecommitdiff
path: root/apt-private/private-cachefile.cc
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2015-07-12 13:41:12 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2015-08-10 17:27:17 +0200
commita0c19a217ca2ed38ae0ecb4b8d2d4f8c4e53289f (patch)
tree54bfe9d9335f1a26e4c687cbba7da51097fa73f8 /apt-private/private-cachefile.cc
parentb17d75804566ced55109b4b0498b7ed0faad389b (diff)
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
Diffstat (limited to 'apt-private/private-cachefile.cc')
-rw-r--r--apt-private/private-cachefile.cc61
1 files changed, 31 insertions, 30 deletions
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 <apt-pkg/configuration.h>
#include <apt-pkg/depcache.h>
#include <apt-pkg/pkgcache.h>
-#include <apt-pkg/cacheiterators.h>
+#include <apt-pkg/cacheset.h>
#include <apt-private/private-output.h>
#include <apt-private/private-cachefile.h>
@@ -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<map_pointer_t> 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