diff options
Diffstat (limited to 'apt-pkg/pkgcachegen.cc')
-rw-r--r-- | apt-pkg/pkgcachegen.cc | 179 |
1 files changed, 113 insertions, 66 deletions
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 373f6625c..3f10b6c40 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<pkgCache::DescIterator> 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); @@ -391,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); @@ -399,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)"), @@ -464,11 +461,8 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator pkgCache::VerIterator ConVersion = D.ParentVer(); Dynamic<pkgCache::VerIterator> 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); } } } @@ -509,19 +503,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<pkgCache::DescIterator> 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); @@ -564,7 +555,7 @@ bool pkgCacheGenerator::MergeFileProvides(ListParser &List) Dynamic<pkgCache::VerIterator> 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)"), @@ -602,8 +593,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; @@ -632,11 +626,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 { @@ -675,6 +672,7 @@ bool pkgCacheGenerator::AddImplicitDepends(pkgCache::GrpIterator &G, bool const coInstall = ((V->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same); pkgCache::PkgIterator D = G.PackageList(); Dynamic<pkgCache::PkgIterator> DynD(D); + map_ptrloc const VerStrIdx = V->VerStr; for (; D.end() != true; D = G.NextPkg(D)) { if (Arch == D.Arch() || D->VersionList == 0) @@ -685,16 +683,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); } @@ -711,17 +709,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); } @@ -767,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 @@ -778,12 +779,37 @@ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver, Ver = pkgCache::VerIterator(Cache,Cache.VerP + Version); //Dynamic<pkgCache::VerIterator> 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; } /*}}}*/ @@ -825,9 +851,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 +862,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)) + map_ptrloc const idxlanguage_code = WriteUniqString(Lang); + 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; } @@ -859,34 +892,48 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, unsigned int const &Type, map_ptrloc* &OldDepLast) { + map_ptrloc index = 0; + if (Version.empty() == false) + { + 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 (OldDepLast != 0 && 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<pkgCache::DepIterator> 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; |