From 71c9e95b223517b5f51c4627f6ad4cce8af0d901 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 13 Jul 2015 16:28:21 +0200 Subject: split-up Dependency struct Having dependency data separated from the link between version/package and the dependency allows use to work on sharing the depdency data a bit as it turns out that many dependencies are in fact duplicates. How many are duplicates various heavily with the sources configured, but for a single Debian release the ballpark is 2 duplicates for each dependency already (e.g. libc6 counts 18410 dependencies, but only 45 unique). Add more releases and the duplicates count only rises to get ~6 for 3 releases. For each architecture a user has configured which given the shear number of dependencies amounts to MBs of duplication. We can cut down on this number, but pay a heavy price for it: In my many releases(3) + architectures(3) test we have a 10% (~ 0.5 sec) increase in cache creationtime, but also 10% less cachesize (~ 10 MB). Further work is needed to rip the whole benefits from this through, so this is just the start. Git-Dch: Ignore --- apt-pkg/cacheiterators.h | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'apt-pkg/cacheiterators.h') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 06deef950..82c5d082b 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -275,6 +275,7 @@ class pkgCache::DescIterator : public Iterator { // Dependency iterator /*{{{*/ class pkgCache::DepIterator : public Iterator { enum {DepVer, DepRev} Type; + DependencyData * S2; public: inline Dependency* OwnerPointer() const { @@ -282,13 +283,12 @@ class pkgCache::DepIterator : public Iterator { } // Iteration - inline DepIterator& operator++() {if (S != Owner->DepP) S = Owner->DepP + - (Type == DepVer ? S->NextDepends : S->NextRevDepends); return *this;} + DepIterator& operator++(); inline DepIterator operator++(int) { DepIterator const tmp(*this); operator++(); return tmp; } // Accessors - inline const char *TargetVer() const {return S->Version == 0?0:Owner->StrP + S->Version;} - inline PkgIterator TargetPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->Package);} + inline const char *TargetVer() const {return S2->Version == 0?0:Owner->StrP + S2->Version;} + inline PkgIterator TargetPkg() const {return PkgIterator(*Owner,Owner->PkgP + S2->Package);} inline PkgIterator SmartTargetPkg() const {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;} inline VerIterator ParentVer() const {return VerIterator(*Owner,Owner->VerP + S->ParentVer);} inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->ParentVer].ParentPkg);} @@ -303,23 +303,48 @@ class pkgCache::DepIterator : public Iterator { void GlobOr(DepIterator &Start,DepIterator &End); Version **AllTargets() const; bool SmartTargetPkg(PkgIterator &Result) const; - inline const char *CompType() const {return Owner->CompType(S->CompareOp);} - inline const char *DepType() const {return Owner->DepType(S->Type);} + inline const char *CompType() const {return Owner->CompType(S2->CompareOp);} + inline const char *DepType() const {return Owner->DepType(S2->Type);} + + // overrides because we are special + struct DependencyProxy + { + map_stringitem_t &Version; + map_pointer_t &Package; + should_be_map_id_t &ID; + unsigned char &Type; + unsigned char &CompareOp; + map_pointer_t &ParentVer; + map_pointer_t &DependencyData; + map_pointer_t &NextRevDepends; + map_pointer_t &NextDepends; + DependencyProxy const * operator->() const { return this; } + DependencyProxy * operator->() { return this; } + }; + inline DependencyProxy operator->() const {return { S2->Version, S2->Package, S->ID, S2->Type, S2->CompareOp, S->ParentVer, S->DependencyData, S->NextRevDepends, S->NextDepends };} + inline DependencyProxy operator->() {return { S2->Version, S2->Package, S->ID, S2->Type, S2->CompareOp, S->ParentVer, S->DependencyData, S->NextRevDepends, S->NextDepends };} + void ReMap(void const * const oldMap, void const * const newMap) + { + Iterator::ReMap(oldMap, newMap); + if (Owner == 0 || S == 0 || S2 == 0) + return; + S2 += (DependencyData const * const)(newMap) - (DependencyData const * const)(oldMap); + } //Nice printable representation friend std::ostream& operator <<(std::ostream& out, DepIterator D); inline DepIterator(pkgCache &Owner, Dependency *Trg, Version* = 0) : - Iterator(Owner, Trg), Type(DepVer) { + Iterator(Owner, Trg), Type(DepVer), S2(Trg == 0 ? Owner.DepDataP : (Owner.DepDataP + Trg->DependencyData)) { if (S == 0) S = Owner.DepP; } inline DepIterator(pkgCache &Owner, Dependency *Trg, Package*) : - Iterator(Owner, Trg), Type(DepRev) { + Iterator(Owner, Trg), Type(DepRev), S2(Trg == 0 ? Owner.DepDataP : (Owner.DepDataP + Trg->DependencyData)) { if (S == 0) S = Owner.DepP; } - inline DepIterator() : Iterator(), Type(DepVer) {} + inline DepIterator() : Iterator(), Type(DepVer), S2(0) {} }; /*}}}*/ // Provides iterator /*{{{*/ -- cgit v1.2.3