From a65e22c64a9312dec90264b4059424dbe2290d7b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 12 Mar 2013 23:28:16 +0100 Subject: * apt-pkg/pkgcachegen.cc: - do not store the MD5Sum for every description language variant as it will be the same for all so it can be shared to save cache space --- apt-pkg/pkgcachegen.cc | 61 ++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 29 deletions(-) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 373f6625c..2f05310c1 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -300,36 +300,35 @@ bool pkgCacheGenerator::MergeListPackage(ListParser &List, pkgCache::PkgIterator for (Ver = Pkg.VersionList(); Ver.end() == false; ++Ver) { - pkgCache::DescIterator Desc = Ver.DescriptionList(); + pkgCache::DescIterator VerDesc = Ver.DescriptionList(); // a version can only have one md5 describing it - if (Desc.end() == true || MD5SumValue(Desc.md5()) != CurMd5) + if (VerDesc.end() == true || MD5SumValue(VerDesc.md5()) != CurMd5) continue; // don't add a new description if we have one for the given // md5 && language - if (IsDuplicateDescription(Desc, CurMd5, CurLang) == true) + if (IsDuplicateDescription(VerDesc, CurMd5, CurLang) == true) continue; + pkgCache::DescIterator Desc; Dynamic DynDesc(Desc); - // we add at the end, so that the start is constant as we need - // that to be able to efficiently share these lists - map_ptrloc *LastDesc = &Ver->DescriptionList; - for (;Desc.end() == false && Desc->NextDesc != 0; ++Desc); - if (Desc.end() == false) - LastDesc = &Desc->NextDesc; - void const * const oldMap = Map.Data(); - map_ptrloc const descindex = NewDescription(Desc, CurLang, CurMd5, *LastDesc); + map_ptrloc const descindex = NewDescription(Desc, CurLang, CurMd5, VerDesc->md5sum); if (unlikely(descindex == 0 && _error->PendingError())) return _error->Error(_("Error occurred while processing %s (%s%d)"), Pkg.Name(), "NewDescription", 1); - if (oldMap != Map.Data()) - LastDesc += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap; - *LastDesc = descindex; + Desc->ParentPkg = Pkg.Index(); - if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false) + // we add at the end, so that the start is constant as we need + // that to be able to efficiently share these lists + VerDesc = Ver.DescriptionList(); // old value might be invalid after ReMap + for (;VerDesc.end() == false && VerDesc->NextDesc != 0; ++VerDesc); + map_ptrloc * const LastNextDesc = (VerDesc.end() == true) ? &Ver->DescriptionList : &VerDesc->NextDesc; + *LastNextDesc = descindex; + + if (NewFileDesc(Desc,List) == false) return _error->Error(_("Error occurred while processing %s (%s%d)"), Pkg.Name(), "NewFileDesc", 1); @@ -509,19 +508,16 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator // We haven't found reusable descriptions, so add the first description pkgCache::DescIterator Desc = Ver.DescriptionList(); Dynamic DynDesc(Desc); - map_ptrloc *LastDesc = &Ver->DescriptionList; - oldMap = Map.Data(); - map_ptrloc const descindex = NewDescription(Desc, CurLang, CurMd5, *LastDesc); + map_ptrloc const descindex = NewDescription(Desc, CurLang, CurMd5, 0); if (unlikely(descindex == 0 && _error->PendingError())) return _error->Error(_("Error occurred while processing %s (%s%d)"), Pkg.Name(), "NewDescription", 2); - if (oldMap != Map.Data()) - LastDesc += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap; - *LastDesc = descindex; + Desc->ParentPkg = Pkg.Index(); + Ver->DescriptionList = descindex; - if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false) + if (NewFileDesc(Desc,List) == false) return _error->Error(_("Error occurred while processing %s (%s%d)"), Pkg.Name(), "NewFileDesc", 2); @@ -825,9 +821,9 @@ bool pkgCacheGenerator::NewFileDesc(pkgCache::DescIterator &Desc, // --------------------------------------------------------------------- /* This puts a description structure in the linked list */ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, - const string &Lang, - const MD5SumValue &md5sum, - map_ptrloc Next) + const string &Lang, + const MD5SumValue &md5sum, + map_ptrloc idxmd5str) { // Get a structure map_ptrloc const Description = AllocateInMap(sizeof(pkgCache::Description)); @@ -836,14 +832,21 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, // Fill it in Desc = pkgCache::DescIterator(Cache,Cache.DescP + Description); - Desc->NextDesc = Next; Desc->ID = Cache.HeaderP->DescriptionCount++; map_ptrloc const idxlanguage_code = WriteStringInMap(Lang); - map_ptrloc const idxmd5sum = WriteStringInMap(md5sum.Value()); - if (unlikely(idxlanguage_code == 0 || idxmd5sum == 0)) + if (unlikely(idxlanguage_code == 0)) return 0; Desc->language_code = idxlanguage_code; - Desc->md5sum = idxmd5sum; + + if (idxmd5str != 0) + Desc->md5sum = idxmd5str; + else + { + map_ptrloc const idxmd5sum = WriteStringInMap(md5sum.Value()); + if (unlikely(idxmd5sum == 0)) + return 0; + Desc->md5sum = idxmd5sum; + } return Description; } -- cgit v1.2.3-70-g09d2 From 734b7c817a54e2717bc9124a691be532d881a65b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 12 Mar 2013 23:47:48 +0100 Subject: handle language tags for descriptions are unique strings to be shared --- apt-pkg/pkgcachegen.cc | 2 +- debian/changelog | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 2f05310c1..d14a7af1c 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -833,7 +833,7 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, // Fill it in Desc = pkgCache::DescIterator(Cache,Cache.DescP + Description); Desc->ID = Cache.HeaderP->DescriptionCount++; - map_ptrloc const idxlanguage_code = WriteStringInMap(Lang); + map_ptrloc const idxlanguage_code = WriteUniqString(Lang); if (unlikely(idxlanguage_code == 0)) return 0; Desc->language_code = idxlanguage_code; diff --git a/debian/changelog b/debian/changelog index 58cff6822..9578ec8fd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,7 @@ apt (0.9.7.8~exp2+nmu1) UNRELEASED; urgency=low * apt-pkg/pkgcachegen.cc: - do not store the MD5Sum for every description language variant as it will be the same for all so it can be shared to save cache space + - handle language tags for descriptions are unique strings to be shared -- David Kalnischkies Sun, 10 Mar 2013 12:23:24 +0100 -- cgit v1.2.3-70-g09d2 From 9c44383f2ea09afbf6ebab217cdc450e5170c172 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 13 Mar 2013 19:00:19 +0100 Subject: factor version string creation out of NewDepends, so we can easily reuse version strings e.g. for implicit multi-arch dependencies --- apt-pkg/pkgcachegen.cc | 57 +++++++++++++++++++++++++++----------------------- apt-pkg/pkgcachegen.h | 3 +++ debian/changelog | 2 ++ 3 files changed, 36 insertions(+), 26 deletions(-) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index d14a7af1c..01aaf6164 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -463,11 +463,8 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator pkgCache::VerIterator ConVersion = D.ParentVer(); Dynamic DynV(ConVersion); // duplicate the Conflicts/Breaks/Replaces for :none arch - if (D->Version == 0) - NewDepends(Pkg, ConVersion, "", 0, D->Type, OldDepLast); - else - NewDepends(Pkg, ConVersion, D.TargetVer(), - D->CompareOp, D->Type, OldDepLast); + NewDepends(Pkg, ConVersion, D->Version, + D->CompareOp, D->Type, OldDepLast); } } } @@ -671,6 +668,7 @@ bool pkgCacheGenerator::AddImplicitDepends(pkgCache::GrpIterator &G, bool const coInstall = ((V->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same); pkgCache::PkgIterator D = G.PackageList(); Dynamic DynD(D); + map_ptrloc const VerStrIdx = V->VerStr; for (; D.end() != true; D = G.NextPkg(D)) { if (Arch == D.Arch() || D->VersionList == 0) @@ -681,16 +679,16 @@ bool pkgCacheGenerator::AddImplicitDepends(pkgCache::GrpIterator &G, if (coInstall == true) { // Replaces: ${self}:other ( << ${binary:Version}) - NewDepends(D, V, V.VerStr(), + NewDepends(D, V, VerStrIdx, pkgCache::Dep::Less, pkgCache::Dep::Replaces, OldDepLast); // Breaks: ${self}:other (!= ${binary:Version}) - NewDepends(D, V, V.VerStr(), + NewDepends(D, V, VerStrIdx, pkgCache::Dep::NotEquals, pkgCache::Dep::DpkgBreaks, OldDepLast); } else { // Conflicts: ${self}:other - NewDepends(D, V, "", + NewDepends(D, V, 0, pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts, OldDepLast); } @@ -707,17 +705,18 @@ bool pkgCacheGenerator::AddImplicitDepends(pkgCache::VerIterator &V, bool const coInstall = ((V->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same); if (coInstall == true) { + map_ptrloc const VerStrIdx = V->VerStr; // Replaces: ${self}:other ( << ${binary:Version}) - NewDepends(D, V, V.VerStr(), + NewDepends(D, V, VerStrIdx, pkgCache::Dep::Less, pkgCache::Dep::Replaces, OldDepLast); // Breaks: ${self}:other (!= ${binary:Version}) - NewDepends(D, V, V.VerStr(), + NewDepends(D, V, VerStrIdx, pkgCache::Dep::NotEquals, pkgCache::Dep::DpkgBreaks, OldDepLast); } else { // Conflicts: ${self}:other - NewDepends(D, V, "", + NewDepends(D, V, 0, pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts, OldDepLast); } @@ -861,35 +860,41 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, unsigned int const &Op, unsigned int const &Type, map_ptrloc* &OldDepLast) +{ + map_ptrloc index = 0; + if (Version.empty() == false) + { + void const * const oldMap = Map.Data(); + index = WriteStringInMap(Version); + if (unlikely(index == 0)) + return false; + if (oldMap != Map.Data()) + OldDepLast += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap; + } + return NewDepends(Pkg, Ver, index, Op, Type, OldDepLast); +} +bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, + pkgCache::VerIterator &Ver, + map_ptrloc const Version, + unsigned int const &Op, + unsigned int const &Type, + map_ptrloc* &OldDepLast) { void const * const oldMap = Map.Data(); // Get a structure map_ptrloc const Dependency = AllocateInMap(sizeof(pkgCache::Dependency)); if (unlikely(Dependency == 0)) return false; - + // Fill it in pkgCache::DepIterator Dep(Cache,Cache.DepP + Dependency); Dynamic DynDep(Dep); Dep->ParentVer = Ver.Index(); Dep->Type = Type; Dep->CompareOp = Op; + Dep->Version = Version; Dep->ID = Cache.HeaderP->DependsCount++; - // Probe the reverse dependency list for a version string that matches - if (Version.empty() == false) - { -/* for (pkgCache::DepIterator I = Pkg.RevDependsList(); I.end() == false; I++) - if (I->Version != 0 && I.TargetVer() == Version) - Dep->Version = I->Version;*/ - if (Dep->Version == 0) { - map_ptrloc const index = WriteStringInMap(Version); - if (unlikely(index == 0)) - return false; - Dep->Version = index; - } - } - // Link it to the package Dep->Package = Pkg.Index(); Dep->NextRevDepends = Pkg->RevDepends; diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index b6259b433..e759cbd3e 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -77,6 +77,9 @@ class pkgCacheGenerator /*{{{*/ bool NewDepends(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver, std::string const &Version, unsigned int const &Op, unsigned int const &Type, map_ptrloc* &OldDepLast); + bool NewDepends(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver, + map_ptrloc const Version, unsigned int const &Op, + unsigned int const &Type, map_ptrloc* &OldDepLast); unsigned long NewVersion(pkgCache::VerIterator &Ver,const std::string &VerStr,unsigned long Next); map_ptrloc NewDescription(pkgCache::DescIterator &Desc,const std::string &Lang,const MD5SumValue &md5sum,map_ptrloc Next); diff --git a/debian/changelog b/debian/changelog index 9578ec8fd..7796f5920 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,8 @@ apt (0.9.7.8~exp2+nmu1) UNRELEASED; urgency=low - do not store the MD5Sum for every description language variant as it will be the same for all so it can be shared to save cache space - handle language tags for descriptions are unique strings to be shared + - factor version string creation out of NewDepends, so we can easily reuse + version strings e.g. for implicit multi-arch dependencies -- David Kalnischkies Sun, 10 Mar 2013 12:23:24 +0100 -- cgit v1.2.3-70-g09d2 From b8a884c0c7d5f670179a82984289140a9f432729 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 1 Apr 2013 15:41:02 +0200 Subject: equal comparisions are used mostly in same-source relations, so use this to try to reuse some version strings --- apt-pkg/pkgcachegen.cc | 20 ++++++++++++++------ debian/changelog | 2 ++ 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 01aaf6164..b11ddcf9e 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -864,12 +864,20 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, map_ptrloc index = 0; if (Version.empty() == false) { - void const * const oldMap = Map.Data(); - index = WriteStringInMap(Version); - if (unlikely(index == 0)) - return false; - if (oldMap != Map.Data()) - OldDepLast += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap; + int const CmpOp = Op & 0x0F; + // =-deps are used (79:1) for lockstep on same-source packages (e.g. data-packages) + if (CmpOp == pkgCache::Dep::Equals && strcmp(Version.c_str(), Ver.VerStr()) == 0) + index = Ver->VerStr; + + if (index == 0) + { + void const * const oldMap = Map.Data(); + index = WriteStringInMap(Version); + if (unlikely(index == 0)) + return false; + if (oldMap != Map.Data()) + OldDepLast += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap; + } } return NewDepends(Pkg, Ver, index, Op, Type, OldDepLast); } diff --git a/debian/changelog b/debian/changelog index b0e669129..d9183db98 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,8 @@ apt (0.9.7.8~exp2+nmu1) UNRELEASED; urgency=low - handle language tags for descriptions are unique strings to be shared - factor version string creation out of NewDepends, so we can easily reuse version strings e.g. for implicit multi-arch dependencies + - equal comparisions are used mostly in same-source relations, + so use this to try to reuse some version strings * apt-pkg/deb/debversion.cc: - add a string-equal shortcut for equal version comparisions -- cgit v1.2.3-70-g09d2 From aa0fe657e46b87cc692895a36df12e8b74bb27bb Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 3 Apr 2013 12:44:36 +0200 Subject: - sort group and package names in the hashtable on insert * apt-pkg/pkgcache.cc: - assume sorted hashtable entries for groups/packages --- apt-pkg/pkgcache.cc | 31 ++++++++++++++++++++----------- apt-pkg/pkgcachegen.cc | 16 +++++++++++----- debian/changelog | 3 +++ 3 files changed, 34 insertions(+), 16 deletions(-) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 1378876fe..879f34099 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -52,7 +52,7 @@ pkgCache::Header::Header() /* Whenever the structures change the major version should be bumped, whenever the generator changes the minor version should be bumped. */ MajorVersion = 8; - MinorVersion = 0; + MinorVersion = 1; Dirty = false; HeaderSz = sizeof(pkgCache::Header); @@ -182,18 +182,17 @@ unsigned long pkgCache::sHash(const string &Str) const { unsigned long Hash = 0; for (string::const_iterator I = Str.begin(); I != Str.end(); ++I) - Hash = 5*Hash + tolower_ascii(*I); + Hash = 41 * Hash + tolower_ascii(*I); return Hash % _count(HeaderP->PkgHashTable); } unsigned long pkgCache::sHash(const char *Str) const { - unsigned long Hash = 0; - for (const char *I = Str; *I != 0; ++I) - Hash = 5*Hash + tolower_ascii(*I); + unsigned long Hash = tolower_ascii(*Str); + for (const char *I = Str + 1; *I != 0; ++I) + Hash = 41 * Hash + tolower_ascii(*I); return Hash % _count(HeaderP->PkgHashTable); } - /*}}}*/ // Cache::SingleArchFindPkg - Locate a package by name /*{{{*/ // --------------------------------------------------------------------- @@ -206,9 +205,14 @@ pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name) Package *Pkg = PkgP + HeaderP->PkgHashTable[Hash(Name)]; for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage) { - if (Pkg->Name != 0 && StrP[Pkg->Name] == Name[0] && - stringcasecmp(Name,StrP + Pkg->Name) == 0) - return PkgIterator(*this,Pkg); + if (unlikely(Pkg->Name == 0)) + continue; + + int const cmp = strcasecmp(Name.c_str(), StrP + Pkg->Name); + if (cmp == 0) + return PkgIterator(*this, Pkg); + else if (cmp < 0) + break; } return PkgIterator(*this,0); } @@ -265,9 +269,14 @@ pkgCache::GrpIterator pkgCache::FindGrp(const string &Name) { // Look at the hash bucket for the group Group *Grp = GrpP + HeaderP->GrpHashTable[sHash(Name)]; for (; Grp != GrpP; Grp = GrpP + Grp->Next) { - if (Grp->Name != 0 && StrP[Grp->Name] == Name[0] && - stringcasecmp(Name, StrP + Grp->Name) == 0) + if (unlikely(Grp->Name == 0)) + continue; + + int const cmp = strcasecmp(Name.c_str(), StrP + Grp->Name); + if (cmp == 0) return GrpIterator(*this, Grp); + else if (cmp < 0) + break; } return GrpIterator(*this,0); diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index b11ddcf9e..8437dc68f 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -595,8 +595,11 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name) // Insert it into the hash table unsigned long const Hash = Cache.Hash(Name); - Grp->Next = Cache.HeaderP->GrpHashTable[Hash]; - Cache.HeaderP->GrpHashTable[Hash] = Group; + map_ptrloc *insertAt = &Cache.HeaderP->GrpHashTable[Hash]; + while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.GrpP + *insertAt)->Name) > 0) + insertAt = &(Cache.GrpP + *insertAt)->Next; + Grp->Next = *insertAt; + *insertAt = Group; Grp->ID = Cache.HeaderP->GroupCount++; return true; @@ -625,11 +628,14 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name // Insert the package into our package list if (Grp->FirstPackage == 0) // the group is new { + Grp->FirstPackage = Package; // Insert it into the hash table unsigned long const Hash = Cache.Hash(Name); - Pkg->NextPackage = Cache.HeaderP->PkgHashTable[Hash]; - Cache.HeaderP->PkgHashTable[Hash] = Package; - Grp->FirstPackage = Package; + map_ptrloc *insertAt = &Cache.HeaderP->PkgHashTable[Hash]; + while (*insertAt != 0 && strcasecmp(Name.c_str(), Cache.StrP + (Cache.PkgP + *insertAt)->Name) > 0) + insertAt = &(Cache.PkgP + *insertAt)->NextPackage; + Pkg->NextPackage = *insertAt; + *insertAt = Package; } else // Group the Packages together { diff --git a/debian/changelog b/debian/changelog index d9183db98..d4f0e4bb3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,6 +10,9 @@ apt (0.9.7.8~exp2+nmu1) UNRELEASED; urgency=low version strings e.g. for implicit multi-arch dependencies - equal comparisions are used mostly in same-source relations, so use this to try to reuse some version strings + - sort group and package names in the hashtable on insert + * apt-pkg/pkgcache.cc: + - assume sorted hashtable entries for groups/packages * apt-pkg/deb/debversion.cc: - add a string-equal shortcut for equal version comparisions -- cgit v1.2.3-70-g09d2 From 885594fc8831d1be5a254557385e3dbefb564fbf Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 3 Apr 2013 19:43:03 +0200 Subject: share version strings between same versions (of different architectures) to save some space and allow quick comparisions later on --- apt-pkg/deb/debversion.cc | 12 ++++-------- apt-pkg/pkgcachegen.cc | 37 +++++++++++++++++++++++++++++++------ apt-pkg/pkgcachegen.h | 6 +++++- debian/changelog | 2 ++ 4 files changed, 42 insertions(+), 15 deletions(-) (limited to 'apt-pkg/pkgcachegen.cc') diff --git a/apt-pkg/deb/debversion.cc b/apt-pkg/deb/debversion.cc index 94d357846..140561262 100644 --- a/apt-pkg/deb/debversion.cc +++ b/apt-pkg/deb/debversion.cc @@ -217,16 +217,12 @@ bool debVersioningSystem::CheckDep(const char *PkgVer, return false; Op &= 0x0F; - size_t const lenPkgVer = strlen(PkgVer); - size_t const lenDepVer = strlen(DepVer); - - // take a shortcut for equals which are string-equal as well - if (Op == pkgCache::Dep::Equals && lenPkgVer == lenDepVer && - memcmp(PkgVer, DepVer, lenPkgVer) == 0) - return true; + // fast track for (equal) strings [by location] which are by definition equal versions + if (PkgVer == DepVer) + return Op == pkgCache::Dep::Equals || Op == pkgCache::Dep::LessEq || Op == pkgCache::Dep::GreaterEq; // Perform the actual comparision. - int const Res = DoCmpVersion(PkgVer, PkgVer + lenPkgVer, DepVer, DepVer + lenDepVer); + int const Res = CmpVersion(PkgVer, DepVer); switch (Op) { case pkgCache::Dep::LessEq: diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 8437dc68f..3f10b6c40 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -390,7 +390,7 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator } // Add a new version - map_ptrloc const verindex = NewVersion(Ver,Version,*LastVer); + map_ptrloc const verindex = NewVersion(Ver, Version, Pkg.Index(), Hash, *LastVer); if (verindex == 0 && _error->PendingError()) return _error->Error(_("Error occurred while processing %s (%s%d)"), Pkg.Name(), "NewVersion", 1); @@ -398,8 +398,6 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator if (oldMap != Map.Data()) LastVer += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap; *LastVer = verindex; - Ver->ParentPkg = Pkg.Index(); - Ver->Hash = Hash; if (unlikely(List.NewVersion(Ver) == false)) return _error->Error(_("Error occurred while processing %s (%s%d)"), @@ -557,7 +555,7 @@ bool pkgCacheGenerator::MergeFileProvides(ListParser &List) Dynamic DynVer(Ver); for (; Ver.end() == false; ++Ver) { - if (Ver->Hash == Hash && Version.c_str() == Ver.VerStr()) + if (Ver->Hash == Hash && Version == Ver.VerStr()) { if (List.CollectFileProvides(Cache,Ver) == false) return _error->Error(_("Error occurred while processing %s (%s%d)"), @@ -768,6 +766,8 @@ bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator &Ver, /* This puts a version structure in the linked list */ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver, const string &VerStr, + map_ptrloc const ParentPkg, + unsigned long const Hash, unsigned long Next) { // Get a structure @@ -779,12 +779,37 @@ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver, Ver = pkgCache::VerIterator(Cache,Cache.VerP + Version); //Dynamic DynV(Ver); // caller MergeListVersion already takes care of it Ver->NextVer = Next; + Ver->ParentPkg = ParentPkg; + Ver->Hash = Hash; Ver->ID = Cache.HeaderP->VersionCount++; + + // try to find the version string in the group for reuse + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + pkgCache::GrpIterator Grp = Pkg.Group(); + if (Pkg.end() == false && Grp.end() == false) + { + for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P)) + { + if (Pkg == P) + continue; + for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V) + { + int const cmp = strcmp(V.VerStr(), VerStr.c_str()); + if (cmp == 0) + { + Ver->VerStr = V->VerStr; + return Version; + } + else if (cmp < 0) + break; + } + } + } + // haven't found the version string, so create map_ptrloc const idxVerStr = WriteStringInMap(VerStr); if (unlikely(idxVerStr == 0)) return 0; Ver->VerStr = idxVerStr; - return Version; } /*}}}*/ @@ -881,7 +906,7 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, index = WriteStringInMap(Version); if (unlikely(index == 0)) return false; - if (oldMap != Map.Data()) + if (OldDepLast != 0 && oldMap != Map.Data()) OldDepLast += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap; } } diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index e759cbd3e..428e8459b 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -80,7 +80,11 @@ class pkgCacheGenerator /*{{{*/ bool NewDepends(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver, map_ptrloc const Version, unsigned int const &Op, unsigned int const &Type, map_ptrloc* &OldDepLast); - unsigned long NewVersion(pkgCache::VerIterator &Ver,const std::string &VerStr,unsigned long Next); + __deprecated unsigned long NewVersion(pkgCache::VerIterator &Ver,const std::string &VerStr,unsigned long Next) + { return NewVersion(Ver, VerStr, 0, 0, Next); } + unsigned long NewVersion(pkgCache::VerIterator &Ver,const std::string &VerStr, + map_ptrloc const ParentPkg, unsigned long const Hash, + unsigned long Next); map_ptrloc NewDescription(pkgCache::DescIterator &Desc,const std::string &Lang,const MD5SumValue &md5sum,map_ptrloc Next); public: diff --git a/debian/changelog b/debian/changelog index 7070c5fc9..9fce4b14e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -11,6 +11,8 @@ apt (0.9.7.8~exp2+nmu1) UNRELEASED; urgency=low - equal comparisions are used mostly in same-source relations, so use this to try to reuse some version strings - sort group and package names in the hashtable on insert + - share version strings between same versions (of different architectures) + to save some space and allow quick comparisions later on * apt-pkg/pkgcache.cc: - assume sorted hashtable entries for groups/packages * apt-pkg/cacheiterators.h: -- cgit v1.2.3-70-g09d2