diff options
author | David Kalnischkies <david@kalnischkies.de> | 2015-07-17 10:53:01 +0200 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2015-08-10 17:27:59 +0200 |
commit | bb0f6a34c4cebea7884de828c011dc85765ff820 (patch) | |
tree | 809a630ba606bac6b9050c97f9ecbccc7562244f /apt-pkg/pkgcachegen.cc | |
parent | ecc138f858fab61e0b888d3d13854d1422c3432b (diff) |
just-in-time creation for (explicit) negative deps
Now that we deal with provides in a more dynamic fashion the last
remaining problem is explicit dependencies like 'Conflicts: foo' which
have to apply to all architectures, but creating them all at the same
time requires us to know all architectures ending up in the cache which
isn't needed to be the same set as all foreign architectures.
The effect is visible already now through as this prevents the creation
of a bunch of virtual packages for arch:all packages and as such also
many dependencies, just not very visible if you don't look at the stats…
Git-Dch Ignore
Diffstat (limited to 'apt-pkg/pkgcachegen.cc')
-rw-r--r-- | apt-pkg/pkgcachegen.cc | 112 |
1 files changed, 69 insertions, 43 deletions
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index c04320555..26a5e60a6 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -695,6 +695,23 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name if (NewProvides(Ver, Pkg, Ver->VerStr, pkgCache::Flag::MultiArchImplicit) == false) return false; } + // and negative dependencies, don't forget negative dependencies + { + pkgCache::PkgIterator const M = Grp.FindPreferredPkg(false); + if (M.end() == false) + for (pkgCache::DepIterator Dep = M.RevDependsList(); Dep.end() == false; ++Dep) + { + if ((Dep->CompareOp & (pkgCache::Dep::ArchSpecific | pkgCache::Dep::MultiArchImplicit)) != 0) + continue; + if (Dep->Type != pkgCache::Dep::DpkgBreaks && Dep->Type != pkgCache::Dep::Conflicts && + Dep->Type != pkgCache::Dep::Replaces) + continue; + pkgCache::VerIterator Ver = Dep.ParentVer(); + map_pointer_t * unused = NULL; + if (NewDepends(Pkg, Ver, Dep->Version, Dep->CompareOp, Dep->Type, unused) == false) + return false; + } + } // this package is the new last package pkgCache::PkgIterator LastPkg(Cache, Cache.PkgP + Grp->LastPackage); @@ -935,33 +952,6 @@ map_pointer_t pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, version and to the package that it is pointing to. */ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver, - string const &Version, - uint8_t const Op, - uint8_t const Type, - map_stringitem_t* &OldDepLast) -{ - map_stringitem_t 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 = StoreString(VERSIONNUMBER, Version); - if (unlikely(index == 0)) - return false; - if (OldDepLast != 0 && oldMap != Map.Data()) - OldDepLast += (map_pointer_t const * const) Map.Data() - (map_pointer_t const * const) oldMap; - } - } - return NewDepends(Pkg, Ver, index, Op, Type, OldDepLast); -} -bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, - pkgCache::VerIterator &Ver, map_pointer_t const Version, uint8_t const Op, uint8_t const Type, @@ -1071,28 +1061,64 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator &Ver, if (unlikely(Owner->NewGroup(Grp, PackageName) == false)) return false; - // Locate the target package - pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch); - // we don't create 'none' packages and their dependencies if we can avoid it … - if (Pkg.end() == true && Arch == "none" && strcmp(Ver.ParentPkg().Arch(), "none") != 0) - return true; - Dynamic<pkgCache::PkgIterator> DynPkg(Pkg); - if (Pkg.end() == true) { - if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false)) - return false; - } - // Is it a file dependency? if (unlikely(PackageName[0] == '/')) FoundFileDeps = true; - /* Caching the old end point speeds up generation substantially */ - if (OldDepVer != Ver) { - OldDepLast = NULL; - OldDepVer = Ver; + map_stringitem_t idxVersion = 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) + idxVersion = Ver->VerStr; + + if (idxVersion == 0) + { + idxVersion = StoreString(VERSIONNUMBER, Version); + if (unlikely(idxVersion == 0)) + return false; + } + } + + bool const isNegative = (Type == pkgCache::Dep::DpkgBreaks || + Type == pkgCache::Dep::Conflicts || + Type == pkgCache::Dep::Replaces); + + pkgCache::PkgIterator Pkg; + Dynamic<pkgCache::PkgIterator> DynPkg(Pkg); + if (isNegative == false || (Op & pkgCache::Dep::ArchSpecific) == pkgCache::Dep::ArchSpecific || Grp->FirstPackage == 0) + { + // Locate the target package + Pkg = Grp.FindPkg(Arch); + if (Pkg.end() == true) { + if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false)) + return false; + } + + /* Caching the old end point speeds up generation substantially */ + if (OldDepVer != Ver) { + OldDepLast = NULL; + OldDepVer = Ver; + } + + return Owner->NewDepends(Pkg, Ver, idxVersion, Op, Type, OldDepLast); } + else + { + /* Caching the old end point speeds up generation substantially */ + if (OldDepVer != Ver) { + OldDepLast = NULL; + OldDepVer = Ver; + } - return Owner->NewDepends(Pkg, Ver, Version, Op, Type, OldDepLast); + for (Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg)) + { + if (Owner->NewDepends(Pkg, Ver, idxVersion, Op, Type, OldDepLast) == false) + return false; + } + } + return true; } /*}}}*/ // ListParser::NewProvides - Create a Provides element /*{{{*/ |