From 4ad8619bb1f0bf777d17c568bb7a6cf7f30aac34 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 12 Jun 2014 12:22:45 +0200 Subject: cleanup datatypes mix used in binary cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We had a wild mixture of (unsigned) int, long and long long here without much sense, so this commit adds a few typedefs to get some sense in the typesystem and ensures that a ID isn't sometimes computed as int, stored as long and compared with a long long… as this could potentially bite us later on as the size of the archive only increases over time. --- apt-pkg/deb/deblistparser.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 40d332196..4447b54dd 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -61,7 +61,7 @@ debListParser::debListParser(FileFd *File, string const &Arch) : Tags(File), // ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/ // --------------------------------------------------------------------- /* */ -unsigned long debListParser::UniqFindTagWrite(const char *Tag) +map_stringitem_t debListParser::UniqFindTagWrite(const char *Tag) { const char *Start; const char *Stop; @@ -893,7 +893,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, { // apt-secure does no longer download individual (per-section) Release // file. to provide Component pinning we use the section name now - map_ptrloc const storage = WriteUniqString(component); + map_stringitem_t const storage = WriteUniqString(component); FileI->Component = storage; pkgTagFile TagFile(&File, File.Size()); @@ -906,7 +906,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, data = Section.FindS(TAG); \ if (data.empty() == false) \ { \ - map_ptrloc const storage = WriteUniqString(data); \ + map_stringitem_t const storage = WriteUniqString(data); \ STORE = storage; \ } APT_INRELEASE("Suite", FileI->Archive) -- cgit v1.2.3-70-g09d2 From 7a66977486804d46d5860f568cbd80f54f0c42d0 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 13 Jun 2014 08:35:32 +0200 Subject: remove the Section member from package struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A version belongs to a section and has hence a section member of its own. A package on the other hand can have multiple versions from different sections. This was "solved" by using the section which was parsed first as order of sources.list defines, but that is obviously a horribly unpredictable thing. We therefore directly remove this struct member to free some space and mark the access method as deprecated, which is told to return the section of the 'newest' known version, which is at least predictable, but possible not what it returned before – but nobody knows. Users are way better of with the Section() as returned by the version they are dealing with. It is likely the same for all versions of a package, but in the few cases it isn't, it is important (like packages moving from main/* to contrib/* or into oldlibs …). --- apt-pkg/cacheiterators.h | 6 +++++- apt-pkg/cacheset.h | 11 ++++++++++- apt-pkg/deb/deblistparser.cc | 3 --- apt-pkg/depcache.cc | 2 +- apt-pkg/pkgcache.cc | 11 ++++++++++- apt-pkg/pkgcache.h | 5 ----- 6 files changed, 26 insertions(+), 12 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 2fdf8404d..f2aae7272 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -160,7 +160,11 @@ class pkgCache::PkgIterator: public Iterator { // Accessors inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;} - inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;} + // Versions have sections - and packages can have different versions with different sections + // so this interface is broken by design. It used to return the section of the "first parsed + // package stanza", but as this can potentially be anything it now returns the section of the + // newest version instead (if any). aka: Run as fast as you can to Version.Section(). + APT_DEPRECATED const char *Section() const; inline bool Purge() const {return S->CurrentState == pkgCache::State::Purge || (S->CurrentVer == 0 && S->CurrentState == pkgCache::State::NotInstalled);} inline const char *Arch() const {return S->Arch == 0?0:Owner->StrP + S->Arch;} diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index dde4e221e..36f41c34d 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -118,7 +118,16 @@ public: inline const char *Name() const {return getPkg().Name(); } inline std::string FullName(bool const Pretty) const { return getPkg().FullName(Pretty); } inline std::string FullName() const { return getPkg().FullName(); } - inline const char *Section() const {return getPkg().Section(); } + APT_DEPRECATED inline const char *Section() const { +#if __GNUC__ >= 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + return getPkg().Section(); +#if __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif + } inline bool Purge() const {return getPkg().Purge(); } inline const char *Arch() const {return getPkg().Arch(); } inline pkgCache::GrpIterator Group() const { return getPkg().Group(); } diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 4447b54dd..192a281db 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -255,9 +255,6 @@ MD5SumValue debListParser::Description_md5() bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver) { - if (Pkg->Section == 0) - Pkg->Section = UniqFindTagWrite("Section"); - string const static myArch = _config->Find("APT::Architecture"); // Possible values are: "all", "native", "installed" and "none" // The "installed" mode is handled by ParseStatus(), See #544481 and friends. diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index c25672d1c..492d16029 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1225,7 +1225,7 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, continue; } // now check if we should consider it a automatic dependency or not - if(InstPkg->CurrentVer == 0 && Pkg->Section != 0 && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", Pkg.Section())) + if(InstPkg->CurrentVer == 0 && InstVer->Section != 0 && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", InstVer.Section())) { if(DebugAutoInstall == true) std::clog << OutputInDepth(Depth) << "Setting NOT as auto-installed (direct " diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 8326741ed..b1ed0129d 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -527,7 +527,10 @@ operator<<(std::ostream& out, pkgCache::PkgIterator Pkg) out << " -> " << candidate; if ( newest != "none" && candidate != newest) out << " | " << newest; - out << " > ( " << string(Pkg.Section()==0?"none":Pkg.Section()) << " )"; + if (Pkg->VersionList == 0) + out << " > ( none )"; + else + out << " > ( " << string(Pkg.VersionList().Section()==0?"unknown":Pkg.VersionList().Section()) << " )"; return out; } /*}}}*/ @@ -1039,3 +1042,9 @@ bool pkgCache::PrvIterator::IsMultiArchImplicit() const return false; } /*}}}*/ +APT_DEPRECATED APT_PURE const char * pkgCache::PkgIterator::Section() const {/*{{{*/ + if (S->VersionList == 0) + return 0; + return VersionList().Section(); +} + /*}}}*/ diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index f57c31b98..0ce2a2878 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -392,11 +392,6 @@ struct pkgCache::Package map_pointer_t VersionList; // Version /** \brief index to the installed version */ map_pointer_t CurrentVer; // Version - /** \brief indicates the deduced section - - Should be the index to the string "Unknown" or to the section - of the last parsed item. */ - map_stringitem_t Section; /** \brief index of the group this package belongs to */ map_pointer_t Group; // Group the Package belongs to -- cgit v1.2.3-70-g09d2 From 4ea471ecb013d188d03a5c3efb9b21e58ef56065 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 7 Jul 2014 17:19:29 +0200 Subject: handle moved mmap after UniqFindTagWrite call A call to UniqFindTagWrite can trigger the need for a bigger mmap, which is usually done by moving it, but with this move all pointers into it become invalid (and have to be remapped). The compiler calculates the pointer before the execution of the call though, so it tries to store the returned value at the old location, resulting in a segfault. We solve this by use of a temprorary variable as we did in the other instances of this problem before. Closes: #753941 --- apt-pkg/deb/deblistparser.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index a1bcfb710..02b9cb239 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -145,7 +145,8 @@ unsigned char debListParser::ParseMultiArch(bool const showErrors) /*{{{*/ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) { // Parse the section - Ver->Section = UniqFindTagWrite("Section"); + unsigned long const idxSection = UniqFindTagWrite("Section"); + Ver->Section = idxSection; Ver->MultiArch = ParseMultiArch(true); // Archive Size Ver->Size = Section.FindULL("Size"); @@ -260,7 +261,10 @@ bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver) { if (Pkg->Section == 0) - Pkg->Section = UniqFindTagWrite("Section"); + { + unsigned long const idxSection = UniqFindTagWrite("Section"); + Pkg->Section = idxSection; + } string const static myArch = _config->Find("APT::Architecture"); // Possible values are: "all", "native", "installed" and "none" -- cgit v1.2.3-70-g09d2 From 8f617600aeb931574baf0b53617e7759baa3f370 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 24 Aug 2014 18:43:07 +0200 Subject: Fix debListParser to accept "no" as a value for the Multi-Arch field Seems this was missed somehow. Closes: #759099 --- apt-pkg/deb/deblistparser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 02b9cb239..28c898542 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -108,7 +108,7 @@ unsigned char debListParser::ParseMultiArch(bool const showErrors) /*{{{*/ { unsigned char MA; string const MultiArch = Section.FindS("Multi-Arch"); - if (MultiArch.empty() == true) + if (MultiArch.empty() == true || MultiArch == "no") MA = pkgCache::Version::None; else if (MultiArch == "same") { if (ArchitectureAll() == true) -- cgit v1.2.3-70-g09d2 From 19fb04e82cdc90d429777fcc4c7a2b33e34d20e5 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 24 Aug 2014 18:43:07 +0200 Subject: Fix debListParser to accept "no" as a value for the Multi-Arch field Seems this was missed somehow. Closes: #759099 --- apt-pkg/deb/deblistparser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 30ae91cca..4ac5aa238 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -108,7 +108,7 @@ unsigned char debListParser::ParseMultiArch(bool const showErrors) /*{{{*/ { unsigned char MA; string const MultiArch = Section.FindS("Multi-Arch"); - if (MultiArch.empty() == true) + if (MultiArch.empty() == true || MultiArch == "no") MA = pkgCache::Version::None; else if (MultiArch == "same") { if (ArchitectureAll() == true) -- cgit v1.2.3-70-g09d2 From 40faab46c4d5fa766c80090f0fdb54120dbb37f2 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 16 Aug 2014 16:33:46 +0200 Subject: support versioned provides as implemented by dpkg APT supported versioned provides for a long while in an attempt to get it working with rpm. While this support is old, we can be relatively sure that it works as versioned provides are used internally to make Multi-Arch:foreign work. Previous versions of apt will print a warning indicating that the versioned provides is ignored, so that something which "Provides: foo (= 2)" doesn't provide anything. Note that dpkg does allow only a equals-relation in the provides line as anything else is deemed too complex. apt doesn't support anything else either and such a support would require potentially big changes. Closes: 758153 --- apt-pkg/deb/deblistparser.cc | 4 +- .../test-bug-758153-versioned-provides-support | 137 +++++++++++++++++++++ 2 files changed, 139 insertions(+), 2 deletions(-) create mode 100755 test/integration/test-bug-758153-versioned-provides-support (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 28c898542..7d4fd52cf 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -803,8 +803,8 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) Start = ParseDepends(Start,Stop,Package,Version,Op); if (Start == 0) return _error->Error("Problem parsing Provides line"); - if (Op != pkgCache::Dep::NoOp) { - _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str()); + if (Op != pkgCache::Dep::NoOp && Op != pkgCache::Dep::Equals) { + _error->Warning("Ignoring Provides line with non-equal DepCompareOp for package %s", Package.c_str()); } else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) { if (NewProvidesAllArch(Ver, Package, Version) == false) return false; diff --git a/test/integration/test-bug-758153-versioned-provides-support b/test/integration/test-bug-758153-versioned-provides-support new file mode 100755 index 000000000..2904ae5a1 --- /dev/null +++ b/test/integration/test-bug-758153-versioned-provides-support @@ -0,0 +1,137 @@ +#!/bin/sh +set -e + +# dpkg implements versioned provides in commit 5bb02fe80e9f40dcad9703a72f67cf615ff217b5 +# but previous versions seem to allow parsing, working and ignoring it. + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework +setupenvironment +configarchitecture 'amd64' 'i386' + +insertinstalledpackage 'webapp' 'all' '1' 'Depends: httpd' +insertinstalledpackage 'webserver' 'all' '1' 'Provides: httpd' + +insertpackage 'unstable' 'webapp' 'all' '2' 'Depends: httpd (>= 2)' +insertpackage 'unstable' 'webserver' 'amd64' '2' 'Provides: httpd (= 2)' +insertpackage 'unstable' 'foreign-webserver' 'i386' '2' 'Multi-Arch: foreign +Provides: httpd (= 2)' + +insertpackage 'experimental' 'webapp' 'all' '3' 'Depends: httpd (>= 1.5)' +insertpackage 'experimental' 'webserver' 'amd64' '3' 'Provides: httpd (= 3)' + +insertpackage 'experimental' 'foreign-webserver' 'i386' '4' 'Multi-Arch: foreign +Provides: httpd (= 4)' +insertpackage 'experimental' 'cool-webapp' 'all' '4' 'Depends: httpd (>= 4)' + +setupaptarchive + +testequal 'Reading package lists... +Building dependency tree... +The following packages will be upgraded: + webapp webserver +2 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Inst webserver [1] (2 unstable [amd64]) +Inst webapp [1] (2 unstable [all]) +Conf webserver (2 unstable [amd64]) +Conf webapp (2 unstable [all])' aptget dist-upgrade -s + +testequal 'Reading package lists... +Building dependency tree... +The following packages will be upgraded: + webapp webserver +2 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Inst webserver [1] (2 unstable [amd64]) +Inst webapp [1] (2 unstable [all]) +Conf webserver (2 unstable [amd64]) +Conf webapp (2 unstable [all])' aptget install webapp webserver -s + +testequal 'Reading package lists... +Building dependency tree... +The following packages will be upgraded: + webapp webserver +2 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Inst webserver [1] (2 unstable [amd64]) +Inst webapp [1] (3 experimental [all]) +Conf webserver (2 unstable [amd64]) +Conf webapp (3 experimental [all])' aptget install webapp=3 webserver -s + +testequal 'Reading package lists... +Building dependency tree... +The following packages will be upgraded: + webapp webserver +2 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Inst webserver [1] (3 experimental [amd64]) +Inst webapp [1] (2 unstable [all]) +Conf webserver (3 experimental [amd64]) +Conf webapp (2 unstable [all])' aptget install webapp webserver=3 -s + +testequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + foreign-webserver:i386 +The following packages will be upgraded: + webapp +1 upgraded, 1 newly installed, 0 to remove and 1 not upgraded. +Inst foreign-webserver:i386 (2 unstable [i386]) +Inst webapp [1] (2 unstable [all]) +Conf foreign-webserver:i386 (2 unstable [i386]) +Conf webapp (2 unstable [all])' aptget install webapp foreign-webserver:i386 -s + +testequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + foreign-webserver:i386 +The following packages will be upgraded: + webapp +1 upgraded, 1 newly installed, 0 to remove and 1 not upgraded. +Inst foreign-webserver:i386 (2 unstable [i386]) +Inst webapp [1] (3 experimental [all]) +Conf foreign-webserver:i386 (2 unstable [i386]) +Conf webapp (3 experimental [all])' aptget install webapp=3 foreign-webserver:i386 -s + +testequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + foreign-webserver:i386 +The following packages will be upgraded: + webapp +1 upgraded, 1 newly installed, 0 to remove and 1 not upgraded. +Inst foreign-webserver:i386 (4 experimental [i386]) +Inst webapp [1] (2 unstable [all]) +Conf foreign-webserver:i386 (4 experimental [i386]) +Conf webapp (2 unstable [all])' aptget install webapp foreign-webserver:i386=4 -s + +testequal 'Reading package lists... +Building dependency tree... +Some packages could not be installed. This may mean that you have +requested an impossible situation or if you are using the unstable +distribution that some required packages have not yet been created +or been moved out of Incoming. +The following information may help to resolve the situation: + +The following packages have unmet dependencies: + cool-webapp : Depends: httpd (>= 4) +E: Unable to correct problems, you have held broken packages.' aptget install cool-webapp -s + +testequal 'Reading package lists... +Building dependency tree... +Some packages could not be installed. This may mean that you have +requested an impossible situation or if you are using the unstable +distribution that some required packages have not yet been created +or been moved out of Incoming. +The following information may help to resolve the situation: + +The following packages have unmet dependencies: + cool-webapp : Depends: httpd (>= 4) +E: Unable to correct problems, you have held broken packages.' aptget install cool-webapp foreign-webserver:i386 -s + +testequal 'Reading package lists... +Building dependency tree... +The following NEW packages will be installed: + cool-webapp foreign-webserver:i386 +0 upgraded, 2 newly installed, 0 to remove and 2 not upgraded. +Inst foreign-webserver:i386 (4 experimental [i386]) +Inst cool-webapp (4 experimental [all]) +Conf foreign-webserver:i386 (4 experimental [i386]) +Conf cool-webapp (4 experimental [all])' aptget install cool-webapp foreign-webserver:i386=4 -s -- cgit v1.2.3-70-g09d2 From 78a5476f3177a2a74ae51a1878c26ca322a25003 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 20 Jun 2014 21:33:56 +0200 Subject: drop stored StringItems in favor of in-memory mappings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Strings like Section names or architectures are needed vary often. Instead of writing them each time we need them, we deploy sharing for these special strings. Until now, this was done with a linked list of strings in which we would search, which was stored in the cache. It turns out we can do this just as well in memory as well with a bunch of std::map's. In memory means here that it isn't available anymore if we have a partly invalid cache, but that isn't much of a problem in practice as the status file is compared to the other files we parse very small and includes mostly duplicates, so the space we would gain by storing is more or less equal to the size of the stored linked list… --- apt-pkg/deb/debindexfile.cc | 2 +- apt-pkg/deb/deblistparser.cc | 45 ++++++++++-------------- apt-pkg/deb/deblistparser.h | 1 - apt-pkg/edsp/edspindexfile.cc | 2 +- apt-pkg/pkgcache.cc | 2 -- apt-pkg/pkgcache.h | 30 ++-------------- apt-pkg/pkgcachegen.cc | 81 ++++++++++++------------------------------- apt-pkg/pkgcachegen.h | 18 ++++++---- 8 files changed, 57 insertions(+), 124 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index feda8d0d8..c35a89ade 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -619,7 +619,7 @@ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const pkgCache::PkgFileIterator CFile = Gen.GetCurFile(); CFile->Size = Pkg.FileSize(); CFile->mtime = Pkg.ModificationTime(); - map_stringitem_t const storage = Gen.WriteUniqString("now"); + map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::MIXED, "now"); CFile->Archive = storage; if (Gen.MergeList(Parser) == false) diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 3e0d3a791..9919d2036 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -58,18 +58,6 @@ debListParser::debListParser(FileFd *File, string const &Arch) : Tags(File), MultiArchEnabled = Architectures.size() > 1; } /*}}}*/ -// ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/ -// --------------------------------------------------------------------- -/* */ -map_stringitem_t debListParser::UniqFindTagWrite(const char *Tag) -{ - const char *Start; - const char *Stop; - if (Section.Find(Tag,Start,Stop) == false) - return 0; - return WriteUniqString(Start,Stop - Start); -} - /*}}}*/ // ListParser::Package - Return the package name /*{{{*/ // --------------------------------------------------------------------- /* This is to return the name of the package this section describes */ @@ -144,9 +132,16 @@ unsigned char debListParser::ParseMultiArch(bool const showErrors) /*{{{*/ /* */ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) { + const char *Start; + const char *Stop; + // Parse the section - unsigned long const idxSection = UniqFindTagWrite("Section"); - Ver->Section = idxSection; + if (Section.Find("Section",Start,Stop) == true) + { + map_stringitem_t const idx = StoreString(pkgCacheGenerator::SECTION, Start, Stop - Start); + Ver->Section = idx; + } + Ver->MultiArch = ParseMultiArch(true); // Archive Size Ver->Size = Section.FindULL("Size"); @@ -155,10 +150,8 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) Ver->InstalledSize *= 1024; // Priority - const char *Start; - const char *Stop; if (Section.Find("Priority",Start,Stop) == true) - { + { if (GrabWord(string(Start,Stop-Start),PrioList,Ver->Priority) == false) Ver->Priority = pkgCache::State::Extra; } @@ -891,7 +884,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, { // apt-secure does no longer download individual (per-section) Release // file. to provide Component pinning we use the section name now - map_stringitem_t const storage = WriteUniqString(component); + map_stringitem_t const storage = StoreString(pkgCacheGenerator::MIXED, component); FileI->Component = storage; pkgTagFile TagFile(&File, File.Size()); @@ -900,19 +893,19 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, return false; std::string data; - #define APT_INRELEASE(TAG, STORE) \ + #define APT_INRELEASE(TYPE, TAG, STORE) \ data = Section.FindS(TAG); \ if (data.empty() == false) \ { \ - map_stringitem_t const storage = WriteUniqString(data); \ + map_stringitem_t const storage = StoreString(pkgCacheGenerator::TYPE, data); \ STORE = storage; \ } - APT_INRELEASE("Suite", FileI->Archive) - APT_INRELEASE("Component", FileI->Component) - APT_INRELEASE("Version", FileI->Version) - APT_INRELEASE("Origin", FileI->Origin) - APT_INRELEASE("Codename", FileI->Codename) - APT_INRELEASE("Label", FileI->Label) + APT_INRELEASE(MIXED, "Suite", FileI->Archive) + APT_INRELEASE(MIXED, "Component", FileI->Component) + APT_INRELEASE(VERSION, "Version", FileI->Version) + APT_INRELEASE(MIXED, "Origin", FileI->Origin) + APT_INRELEASE(MIXED, "Codename", FileI->Codename) + APT_INRELEASE(MIXED, "Label", FileI->Label) #undef APT_INRELEASE Section.FindFlag("NotAutomatic", FileI->Flags, pkgCache::Flag::NotAutomatic); Section.FindFlag("ButAutomaticUpgrades", FileI->Flags, pkgCache::Flag::ButAutomaticUpgrades); diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index f5ac47e1e..b55e57d41 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -49,7 +49,6 @@ class debListParser : public pkgCacheGenerator::ListParser std::vector Architectures; bool MultiArchEnabled; - map_stringitem_t UniqFindTagWrite(const char *Tag); virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver); bool ParseDepends(pkgCache::VerIterator &Ver,const char *Tag, unsigned int Type); diff --git a/apt-pkg/edsp/edspindexfile.cc b/apt-pkg/edsp/edspindexfile.cc index e013dd44c..c38f24567 100644 --- a/apt-pkg/edsp/edspindexfile.cc +++ b/apt-pkg/edsp/edspindexfile.cc @@ -56,7 +56,7 @@ bool edspIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const pkgCache::PkgFileIterator CFile = Gen.GetCurFile(); CFile->Size = Pkg.FileSize(); CFile->mtime = Pkg.ModificationTime(); - map_stringitem_t const storage = Gen.WriteUniqString("edsp::scenario"); + map_stringitem_t const storage = Gen.StoreString(pkgCacheGenerator::MIXED, "edsp::scenario"); CFile->Archive = storage; if (Gen.MergeList(Parser) == false) diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 4b4631a65..4ab9e2a4b 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -82,7 +82,6 @@ pkgCache::Header::Header() MaxDescFileSize = 0; FileList = 0; - StringList = 0; VerSysName = 0; Architecture = 0; HashTableSize = _config->FindI("APT::Cache-HashTableSize", 10 * 1048); @@ -140,7 +139,6 @@ bool pkgCache::ReMap(bool const &Errorchecks) DescP = (Description *)Map.Data(); ProvideP = (Provides *)Map.Data(); DepP = (Dependency *)Map.Data(); - StringItemP = (StringItem *)Map.Data(); StrP = (char *)Map.Data(); if (Errorchecks == false) diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 8179e05aa..4284a318c 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -109,7 +109,6 @@ class pkgCache /*{{{*/ struct Description; struct Provides; struct Dependency; - struct StringItem; struct VerFile; struct DescFile; @@ -186,7 +185,6 @@ class pkgCache /*{{{*/ Description *DescP; Provides *ProvideP; Dependency *DepP; - StringItem *StringItemP; char *StrP; virtual bool ReMap(bool const &Errorchecks = true); @@ -290,12 +288,6 @@ struct pkgCache::Header The PackageFile structures are singly linked lists that represent all package files that have been merged into the cache. */ map_pointer_t FileList; - /** \brief index of the first StringItem structure - - The cache contains a list of all the unique strings (StringItems). - The parser reads this list into memory so it can match strings - against it.*/ - map_pointer_t StringList; /** \brief String representing the version system used */ map_pointer_t VerSysName; /** \brief native architecture the cache was built against */ @@ -438,7 +430,7 @@ struct pkgCache::Package struct pkgCache::PackageFile { /** \brief physical disk file that this PackageFile represents */ - map_pointer_t FileName; // StringItem + map_stringitem_t FileName; /** \brief the release information Please see the files document for a description of what the @@ -606,7 +598,7 @@ struct pkgCache::Description struct pkgCache::Dependency { /** \brief string of the version the dependency is applied against */ - map_stringitem_t Version; // StringItem + map_stringitem_t Version; /** \brief index of the package this depends applies to The generator will - if the package does not already exist - @@ -656,24 +648,6 @@ struct pkgCache::Provides map_pointer_t NextPkgProv; // Provides }; /*}}}*/ -// StringItem structure /*{{{*/ -/** \brief used for generating single instances of strings - - Some things like Section Name are are useful to have as unique tags. - It is part of a linked list based at pkgCache::Header::StringList - - All strings are simply inlined any place in the file that is natural - for the writer. The client should make no assumptions about the positioning - of strings. All StringItems should be null-terminated. */ -struct pkgCache::StringItem -{ - /** \brief string this refers to */ - map_stringitem_t String; - /** \brief Next link in the chain */ - map_stringitem_t NextItem; -}; - /*}}}*/ - inline char const * pkgCache::NativeArch() { return StrP + HeaderP->Architecture; } diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 359dffc9d..f7480bc77 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -57,8 +57,7 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) : FoundFileDeps(0) { CurrentFile = 0; - memset(UniqHash,0,sizeof(UniqHash)); - + if (_error->PendingError() == true) return; @@ -82,9 +81,7 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) : if (unlikely(idxVerSysName == 0)) return; Cache.HeaderP->VerSysName = idxVerSysName; - // this pointer is set in ReMap, but we need it now for WriteUniqString - Cache.StringItemP = (pkgCache::StringItem *)Map.Data(); - map_stringitem_t const idxArchitecture = WriteUniqString(_config->Find("APT::Architecture")); + map_stringitem_t const idxArchitecture = StoreString(MIXED, _config->Find("APT::Architecture")); if (unlikely(idxArchitecture == 0)) return; Cache.HeaderP->Architecture = idxArchitecture; @@ -149,10 +146,6 @@ void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newM CurrentFile += (pkgCache::PackageFile const * const) newMap - (pkgCache::PackageFile const * const) oldMap; - for (size_t i = 0; i < _count(UniqHash); ++i) - if (UniqHash[i] != 0) - UniqHash[i] += (pkgCache::StringItem const * const) newMap - (pkgCache::StringItem const * const) oldMap; - for (std::vector::const_iterator i = Dynamic::toReMap.begin(); i != Dynamic::toReMap.end(); ++i) (*i)->ReMap(oldMap, newMap); @@ -685,7 +678,7 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name #endif Pkg->Group = Grp.Index(); // all is mapped to the native architecture - map_stringitem_t const idxArch = (Arch == "all") ? Cache.HeaderP->Architecture : WriteUniqString(Arch.c_str()); + map_stringitem_t const idxArch = (Arch == "all") ? Cache.HeaderP->Architecture : StoreString(MIXED, Arch); if (unlikely(idxArch == 0)) return false; Pkg->Arch = idxArch; @@ -900,7 +893,7 @@ map_pointer_t pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc, // Fill it in Desc = pkgCache::DescIterator(Cache,Cache.DescP + Description); Desc->ID = Cache.HeaderP->DescriptionCount++; - map_stringitem_t const idxlanguage_code = WriteUniqString(Lang); + map_stringitem_t const idxlanguage_code = StoreString(MIXED, Lang); if (unlikely(idxlanguage_code == 0)) return 0; Desc->language_code = idxlanguage_code; @@ -1102,7 +1095,7 @@ bool pkgCacheGenerator::SelectFile(const string &File,const string &Site, // Fill it in map_stringitem_t const idxFileName = WriteStringInMap(File); - map_stringitem_t const idxSite = WriteUniqString(Site); + map_stringitem_t const idxSite = StoreString(MIXED, Site); if (unlikely(idxFileName == 0 || idxSite == 0)) return false; CurrentFile->FileName = idxFileName; @@ -1110,7 +1103,7 @@ bool pkgCacheGenerator::SelectFile(const string &File,const string &Site, CurrentFile->NextFile = Cache.HeaderP->FileList; CurrentFile->Flags = Flags; CurrentFile->ID = Cache.HeaderP->PackageFileCount; - map_stringitem_t const idxIndexType = WriteUniqString(Index.GetType()->Label); + map_stringitem_t const idxIndexType = StoreString(MIXED, Index.GetType()->Label); if (unlikely(idxIndexType == 0)) return false; CurrentFile->IndexType = idxIndexType; @@ -1127,57 +1120,27 @@ bool pkgCacheGenerator::SelectFile(const string &File,const string &Site, // --------------------------------------------------------------------- /* This is used to create handles to strings. Given the same text it always returns the same number */ -map_stringitem_t pkgCacheGenerator::WriteUniqString(const char *S, +map_stringitem_t pkgCacheGenerator::StoreString(enum StringType const type, const char *S, unsigned int Size) { - /* We use a very small transient hash table here, this speeds up generation - by a fair amount on slower machines */ - pkgCache::StringItem *&Bucket = UniqHash[(S[0]*5 + S[1]) % _count(UniqHash)]; - if (Bucket != 0 && - stringcmp(S,S+Size,Cache.StrP + Bucket->String) == 0) - return Bucket->String; - - // Search for an insertion point - pkgCache::StringItem *I = Cache.StringItemP + Cache.HeaderP->StringList; - int Res = 1; - map_stringitem_t *Last = &Cache.HeaderP->StringList; - for (; I != Cache.StringItemP; Last = &I->NextItem, - I = Cache.StringItemP + I->NextItem) - { - Res = stringcmp(S,S+Size,Cache.StrP + I->String); - if (Res >= 0) - break; + std::string const key(S, Size); + + std::map * strings; + switch(type) { + case MIXED: strings = &strMixed; break; + case PKGNAME: strings = &strPkgNames; break; + case VERSION: strings = &strVersions; break; + case SECTION: strings = &strSections; break; + default: _error->Fatal("Unknown enum type used for string storage of '%s'", key.c_str()); return 0; } - - // Match - if (Res == 0) - { - Bucket = I; - return I->String; - } - - // Get a structure - void const * const oldMap = Map.Data(); - map_pointer_t const Item = AllocateInMap(sizeof(pkgCache::StringItem)); - if (Item == 0) - return 0; - - map_stringitem_t const idxString = WriteStringInMap(S,Size); - if (unlikely(idxString == 0)) - return 0; - if (oldMap != Map.Data()) { - Last += (map_pointer_t const * const) Map.Data() - (map_pointer_t const * const) oldMap; - I += (pkgCache::StringItem const * const) Map.Data() - (pkgCache::StringItem const * const) oldMap; - } - *Last = Item; - // Fill in the structure - pkgCache::StringItem *ItemP = Cache.StringItemP + Item; - ItemP->NextItem = I - Cache.StringItemP; - ItemP->String = idxString; + std::map::const_iterator const item = strings->find(key); + if (item != strings->end()) + return item->second; - Bucket = ItemP; - return ItemP->String; + map_stringitem_t const idxString = WriteStringInMap(S,Size); + strings->insert(std::make_pair(key, idxString)); + return idxString; } /*}}}*/ // CheckValidity - Check that a cache is up-to-date /*{{{*/ diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index 42da7b12d..84777b912 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -27,6 +27,7 @@ #include #include +#include class FileFd; class pkgSourceList; @@ -36,13 +37,16 @@ class pkgIndexFile; class pkgCacheGenerator /*{{{*/ { private: - - pkgCache::StringItem *UniqHash[26]; APT_HIDDEN map_stringitem_t WriteStringInMap(std::string const &String) { return WriteStringInMap(String.c_str()); }; APT_HIDDEN map_stringitem_t WriteStringInMap(const char *String); APT_HIDDEN map_stringitem_t WriteStringInMap(const char *String, const unsigned long &Len); APT_HIDDEN map_pointer_t AllocateInMap(const unsigned long &size); + std::map strMixed; + std::map strSections; + std::map strPkgNames; + std::map strVersions; + public: class ListParser; @@ -91,8 +95,9 @@ class pkgCacheGenerator /*{{{*/ public: - map_stringitem_t WriteUniqString(const char *S,unsigned int const Size); - inline map_stringitem_t WriteUniqString(const std::string &S) {return WriteUniqString(S.c_str(),S.length());}; + enum StringType { MIXED, PKGNAME, VERSION, SECTION }; + map_stringitem_t StoreString(enum StringType const type, const char * S, unsigned int const Size); + inline map_stringitem_t StoreString(enum StringType const type, const std::string &S) {return StoreString(type, S.c_str(),S.length());}; void DropProgress() {Progress = 0;}; bool SelectFile(const std::string &File,const std::string &Site,pkgIndexFile const &Index, @@ -145,8 +150,9 @@ class pkgCacheGenerator::ListParser protected: - inline map_stringitem_t WriteUniqString(std::string S) {return Owner->WriteUniqString(S);}; - inline map_stringitem_t WriteUniqString(const char *S,unsigned int Size) {return Owner->WriteUniqString(S,Size);}; + inline map_stringitem_t StoreString(pkgCacheGenerator::StringType const type, std::string const &S) {return Owner->StoreString(type, S);}; + inline map_stringitem_t StoreString(pkgCacheGenerator::StringType const type, const char *S,unsigned int Size) {return Owner->StoreString(type, S, Size);}; + inline map_stringitem_t WriteString(const std::string &S) {return Owner->WriteStringInMap(S);}; inline map_stringitem_t WriteString(const char *S,unsigned int Size) {return Owner->WriteStringInMap(S,Size);}; bool NewDepends(pkgCache::VerIterator &Ver,const std::string &Package, const std::string &Arch, -- cgit v1.2.3-70-g09d2 From a221efc331693f8905da870141756c892911c433 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 20 Jun 2014 19:34:40 +0200 Subject: store source name and version in binary cache Accessing the package records to acquire this information is pretty costly, so that information wasn't used so far in many places. The most noticeable user by far is EDSP at the moment, but there are ideas to change that which this commit tries to enable. --- apt-pkg/cacheiterators.h | 6 +++++ apt-pkg/deb/deblistparser.cc | 51 +++++++++++++++++++++++++++++++++++ apt-pkg/deb/dpkgpm.cc | 7 +---- apt-pkg/edsp.cc | 6 +---- apt-pkg/pkgcache.h | 6 +++++ cmdline/apt-cache.cc | 2 ++ cmdline/apt-get.cc | 64 +++++++++++++++----------------------------- 7 files changed, 89 insertions(+), 53 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 12a03eb07..b0c02d4a2 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -215,6 +215,12 @@ class pkgCache::VerIterator : public Iterator { // Accessors inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;} inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;} + /** \brief source package name this version comes from + Always contains the name, even if it is the same as the binary name */ + inline const char *SourcePkgName() const {return Owner->StrP + S->SourcePkgName;} + /** \brief source version this version comes from + Always contains the version string, even if it is the same as the binary version */ + inline const char *SourceVerStr() const {return Owner->StrP + S->SourceVerStr;} inline const char *Arch() const { if ((S->MultiArch & pkgCache::Version::All) == pkgCache::Version::All) return "all"; diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 9919d2036..103b126de 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -141,6 +141,57 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) map_stringitem_t const idx = StoreString(pkgCacheGenerator::SECTION, Start, Stop - Start); Ver->Section = idx; } + // Parse the source package name + pkgCache::GrpIterator const G = Ver.ParentPkg().Group(); + Ver->SourcePkgName = G->Name; + Ver->SourceVerStr = Ver->VerStr; + if (Section.Find("Source",Start,Stop) == true) + { + const char * const Space = (const char * const) memchr(Start, ' ', Stop - Start); + pkgCache::VerIterator V; + + if (Space != NULL) + { + Stop = Space; + const char * const Open = (const char * const) memchr(Space, '(', Stop - Space); + if (likely(Open != NULL)) + { + const char * const Close = (const char * const) memchr(Open, ')', Stop - Open); + if (likely(Close != NULL)) + { + std::string const version(Open + 1, (Close - Open) - 1); + if (version != Ver.VerStr()) + { + map_stringitem_t const idx = StoreString(pkgCacheGenerator::VERSION, version); + Ver->SourceVerStr = idx; + } + } + } + } + + std::string const pkgname(Start, Stop - Start); + if (pkgname != G.Name()) + { + for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P)) + { + for (V = P.VersionList(); V.end() == false; ++V) + { + if (pkgname == V.SourcePkgName()) + { + Ver->SourcePkgName = V->SourcePkgName; + break; + } + } + if (V.end() == false) + break; + } + if (V.end() == true) + { + map_stringitem_t const idx = StoreString(pkgCacheGenerator::PKGNAME, pkgname); + Ver->SourcePkgName = idx; + } + } + } Ver->MultiArch = ParseMultiArch(true); // Archive Size diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index a5c05d5ea..95fae9a28 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1754,11 +1754,6 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) if (Ver.end() == true) return; pkgver = Ver.VerStr() == NULL ? "unknown" : Ver.VerStr(); - pkgRecords Recs(Cache); - pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); - srcpkgname = Parse.SourcePkg(); - if(srcpkgname.empty()) - srcpkgname = pkgname; // if the file exists already, we check: // - if it was reported already (touched by apport). @@ -1809,7 +1804,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) time_t now = time(NULL); fprintf(report, "Date: %s" , ctime(&now)); fprintf(report, "Package: %s %s\n", pkgname.c_str(), pkgver.c_str()); - fprintf(report, "SourcePackage: %s\n", srcpkgname.c_str()); + fprintf(report, "SourcePackage: %s\n", Ver.SourcePkgName()); fprintf(report, "ErrorMessage:\n %s\n", errormsg); // ensure that the log is flushed diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index 0d0418e06..2ba914b16 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -95,12 +95,8 @@ bool EDSP::WriteLimitedScenario(pkgDepCache &Cache, FILE* output, void EDSP::WriteScenarioVersion(pkgDepCache &Cache, FILE* output, pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const &Ver) { - pkgRecords Recs(Cache); - pkgRecords::Parser &rec = Recs.Lookup(Ver.FileList()); - string srcpkg = rec.SourcePkg().empty() ? Pkg.Name() : rec.SourcePkg(); - fprintf(output, "Package: %s\n", Pkg.Name()); - fprintf(output, "Source: %s\n", srcpkg.c_str()); + fprintf(output, "Source: %s\n", Ver.SourcePkgName()); fprintf(output, "Architecture: %s\n", Ver.Arch()); fprintf(output, "Version: %s\n", Ver.VerStr()); if (Pkg.CurrentVer() == Ver) diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 4284a318c..6a89eabd7 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -510,6 +510,12 @@ struct pkgCache::Version map_stringitem_t VerStr; /** \brief section this version is filled in */ map_stringitem_t Section; + /** \brief source package name this version comes from + Always contains the name, even if it is the same as the binary name */ + map_stringitem_t SourcePkgName; + /** \brief source version this version comes from + Always contains the version string, even if it is the same as the binary version */ + map_stringitem_t SourceVerStr; /** \brief Multi-Arch capabilities of a package version */ enum VerMultiArch { None = 0, /*!< is the default and doesn't trigger special behaviour */ diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index 5a5dde088..0f4f7e1ce 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -389,6 +389,8 @@ static bool Stats(CommandLine &) stritems.insert(V->VerStr); if (V->Section != 0) stritems.insert(V->Section); + stritems.insert(V->SourcePkgName); + stritems.insert(V->SourceVerStr); for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ++D) { if (D->Version != 0) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index aed1beb4d..a5cafc39d 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -195,7 +195,7 @@ static std::string GetReleaseForSourceRecord(pkgSourceList *SrcList, // FindSrc - Find a source record /*{{{*/ // --------------------------------------------------------------------- /* */ -static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, +static pkgSrcRecords::Parser *FindSrc(const char *Name, pkgSrcRecords &SrcRecs,string &Src, CacheFile &CacheFile) { @@ -303,16 +303,10 @@ static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, (VF.File().Archive() != 0 && VF.File().Archive() == RelTag) || (VF.File().Codename() != 0 && VF.File().Codename() == RelTag)) { - pkgRecords::Parser &Parse = Recs.Lookup(VF); - Src = Parse.SourcePkg(); - // no SourcePkg name, so it is the "binary" name - if (Src.empty() == true) - Src = TmpSrc; + Src = Ver.SourcePkgName(); // the Version we have is possibly fuzzy or includes binUploads, - // so we use the Version of the SourcePkg (empty if same as package) - VerTag = Parse.SourceVer(); - if (VerTag.empty() == true) - VerTag = Ver.VerStr(); + // so we use the Version of the SourcePkg + VerTag = Ver.SourceVerStr(); break; } } @@ -343,10 +337,10 @@ static pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, pkgCache::VerIterator Ver = Cache->GetCandidateVer(Pkg); if (Ver.end() == false) { - pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); - Src = Parse.SourcePkg(); - if (VerTag.empty() == true) - VerTag = Parse.SourceVer(); + if (strcmp(Ver.SourcePkgName(),Ver.ParentPkg().Name()) != 0) + Src = Ver.SourcePkgName(); + if (VerTag.empty() == true && strcmp(Ver.SourceVerStr(),Ver.VerStr()) != 0) + VerTag = Ver.SourceVerStr(); } } } @@ -731,7 +725,6 @@ static bool DoSource(CommandLine &CmdL) pkgSourceList *List = Cache.GetSourceList(); // Create the text record parsers - pkgRecords Recs(Cache); pkgSrcRecords SrcRecs(*List); if (_error->PendingError() == true) return false; @@ -760,7 +753,7 @@ static bool DoSource(CommandLine &CmdL) for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; - pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); + pkgSrcRecords::Parser *Last = FindSrc(*I,SrcRecs,Src,Cache); if (Last == 0) { return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); @@ -1037,7 +1030,6 @@ static bool DoBuildDep(CommandLine &CmdL) pkgSourceList *List = Cache.GetSourceList(); // Create the text record parsers - pkgRecords Recs(Cache); pkgSrcRecords SrcRecs(*List); if (_error->PendingError() == true) return false; @@ -1090,7 +1082,7 @@ static bool DoBuildDep(CommandLine &CmdL) Last = Type->CreateSrcPkgParser(*I); } else { // normal case, search the cache for the source file - Last = FindSrc(*I,Recs,SrcRecs,Src,Cache); + Last = FindSrc(*I,SrcRecs,Src,Cache); } if (Last == 0) @@ -1441,21 +1433,15 @@ static bool DoBuildDep(CommandLine &CmdL) * pool/ next to the deb itself) * Example return: "pool/main/a/apt/apt_0.8.8ubuntu3" */ -static string GetChangelogPath(CacheFile &Cache, - pkgCache::PkgIterator Pkg, +static string GetChangelogPath(CacheFile &Cache, pkgCache::VerIterator Ver) { - string path; - pkgRecords Recs(Cache); pkgRecords::Parser &rec=Recs.Lookup(Ver.FileList()); - string srcpkg = rec.SourcePkg().empty() ? Pkg.Name() : rec.SourcePkg(); - string ver = Ver.VerStr(); - // if there is a source version it always wins - if (rec.SourceVer() != "") - ver = rec.SourceVer(); - path = flNotFile(rec.FileName()); - path += srcpkg + "_" + StripEpoch(ver); + string path = flNotFile(rec.FileName()); + path.append(Ver.SourcePkgName()); + path.append("_"); + path.append(StripEpoch(Ver.SourceVerStr())); return path; } /*}}}*/ @@ -1469,7 +1455,6 @@ static string GetChangelogPath(CacheFile &Cache, * http://packages.medibuntu.org/pool/non-free/m/mplayer/mplayer_1.0~rc4~try1.dsfg1-1ubuntu1+medibuntu1.changelog */ static bool GuessThirdPartyChangelogUri(CacheFile &Cache, - pkgCache::PkgIterator Pkg, pkgCache::VerIterator Ver, string &out_uri) { @@ -1484,7 +1469,7 @@ static bool GuessThirdPartyChangelogUri(CacheFile &Cache, return false; // get archive uri for the binary deb - string path_without_dot_changelog = GetChangelogPath(Cache, Pkg, Ver); + string path_without_dot_changelog = GetChangelogPath(Cache, Ver); out_uri = index->ArchiveURI(path_without_dot_changelog + ".changelog"); // now strip away the filename and add srcpkg_srcver.changelog @@ -1502,25 +1487,20 @@ static bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, * GuessThirdPartyChangelogUri for details how) */ { - string path; - string descr; - string server; - string changelog_uri; - - // data structures we need - pkgCache::PkgIterator Pkg = Ver.ParentPkg(); - // make the server root configurable - server = _config->Find("Apt::Changelogs::Server", + string const server = _config->Find("Apt::Changelogs::Server", "http://packages.debian.org/changelogs"); - path = GetChangelogPath(CacheFile, Pkg, Ver); + string const path = GetChangelogPath(CacheFile, Ver); + string changelog_uri; strprintf(changelog_uri, "%s/%s/changelog", server.c_str(), path.c_str()); if (_config->FindB("APT::Get::Print-URIs", false) == true) { std::cout << '\'' << changelog_uri << '\'' << std::endl; return true; } + pkgCache::PkgIterator const Pkg = Ver.ParentPkg(); + string descr; strprintf(descr, _("Changelog for %s (%s)"), Pkg.Name(), changelog_uri.c_str()); // queue it new pkgAcqFile(&Fetcher, changelog_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); @@ -1531,7 +1511,7 @@ static bool DownloadChangelog(CacheFile &CacheFile, pkgAcquire &Fetcher, if (!FileExists(targetfile)) { string third_party_uri; - if (GuessThirdPartyChangelogUri(CacheFile, Pkg, Ver, third_party_uri)) + if (GuessThirdPartyChangelogUri(CacheFile, Ver, third_party_uri)) { strprintf(descr, _("Changelog for %s (%s)"), Pkg.Name(), third_party_uri.c_str()); new pkgAcqFile(&Fetcher, third_party_uri, "", 0, descr, Pkg.Name(), "ignored", targetfile); -- cgit v1.2.3-70-g09d2 From 30b45652d6b8c710e7a5e7e95cfa431a5df4462c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 3 Oct 2014 00:18:53 +0200 Subject: rename StringType VERSION to VERSIONNUMBER aptitude has a define for VERSION, so to not generate a FTBFS we just rename our enum element to a slightly less generic name. Git-Dch: Ignore --- apt-pkg/deb/deblistparser.cc | 4 ++-- apt-pkg/pkgcachegen.cc | 6 +++--- apt-pkg/pkgcachegen.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 103b126de..63414c944 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -162,7 +162,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) std::string const version(Open + 1, (Close - Open) - 1); if (version != Ver.VerStr()) { - map_stringitem_t const idx = StoreString(pkgCacheGenerator::VERSION, version); + map_stringitem_t const idx = StoreString(pkgCacheGenerator::VERSIONNUMBER, version); Ver->SourceVerStr = idx; } } @@ -953,7 +953,7 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, } APT_INRELEASE(MIXED, "Suite", FileI->Archive) APT_INRELEASE(MIXED, "Component", FileI->Component) - APT_INRELEASE(VERSION, "Version", FileI->Version) + APT_INRELEASE(VERSIONNUMBER, "Version", FileI->Version) APT_INRELEASE(MIXED, "Origin", FileI->Origin) APT_INRELEASE(MIXED, "Codename", FileI->Codename) APT_INRELEASE(MIXED, "Label", FileI->Label) diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 6bb246e9f..9e6931fa6 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -836,7 +836,7 @@ map_pointer_t pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver, } } // haven't found the version string, so create - map_stringitem_t const idxVerStr = StoreString(VERSION, VerStr); + map_stringitem_t const idxVerStr = StoreString(VERSIONNUMBER, VerStr); if (unlikely(idxVerStr == 0)) return 0; Ver->VerStr = idxVerStr; @@ -933,7 +933,7 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg, if (index == 0) { void const * const oldMap = Map.Data(); - index = StoreString(VERSION, Version); + index = StoreString(VERSIONNUMBER, Version); if (unlikely(index == 0)) return false; if (OldDepLast != 0 && oldMap != Map.Data()) @@ -1129,7 +1129,7 @@ map_stringitem_t pkgCacheGenerator::StoreString(enum StringType const type, cons switch(type) { case MIXED: strings = &strMixed; break; case PKGNAME: strings = &strPkgNames; break; - case VERSION: strings = &strVersions; break; + case VERSIONNUMBER: strings = &strVersions; break; case SECTION: strings = &strSections; break; default: _error->Fatal("Unknown enum type used for string storage of '%s'", key.c_str()); return 0; } diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index e1d22b88f..54c4f9e7a 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -95,8 +95,8 @@ class pkgCacheGenerator /*{{{*/ public: - enum StringType { MIXED, PKGNAME, VERSION, SECTION }; - map_stringitem_t StoreString(enum StringType const type, const char * S, unsigned int const Size); + enum StringType { MIXED, PKGNAME, VERSIONNUMBER, SECTION }; + map_stringitem_t StoreString(StringType const type, const char * S, unsigned int const Size); inline map_stringitem_t StoreString(enum StringType const type, const std::string &S) {return StoreString(type, S.c_str(),S.length());}; void DropProgress() {Progress = 0;}; -- cgit v1.2.3-70-g09d2