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 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 +- 1 file changed, 1 insertion(+), 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; -- cgit v1.2.3 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 +++++++++++++++++++++++++++----------------------- 1 file changed, 31 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; -- cgit v1.2.3 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 ++++++++++++++------ 1 file changed, 14 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); } -- cgit v1.2.3 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/pkgcachegen.cc | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'apt-pkg/pkgcachegen.cc') 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 { -- cgit v1.2.3 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/pkgcachegen.cc | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'apt-pkg/pkgcachegen.cc') 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; } } -- cgit v1.2.3