From b0f4b486e6850c5f98520ccf19da71d0ed748ae4 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sun, 21 Sep 2014 10:18:03 +0200 Subject: generalize Acquire::GzipIndex --- apt-pkg/deb/debindexfile.cc | 60 ++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 22 deletions(-) (limited to 'apt-pkg/deb') diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index a0dd15cd8..5b4289e92 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -80,14 +80,18 @@ pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const { string SourcesURI = _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI("Sources")); - string SourcesURIgzip = SourcesURI + ".gz"; - if (!FileExists(SourcesURI) && !FileExists(SourcesURIgzip)) - return NULL; - else if (!FileExists(SourcesURI) && FileExists(SourcesURIgzip)) - SourcesURI = SourcesURIgzip; - - return new debSrcRecordParser(SourcesURI,this); + std::vector types = APT::Configuration::getCompressionTypes(); + for (std::vector::const_iterator t = types.begin(); t != types.end(); ++t) + { + string p; + p = SourcesURI + '.' + *t; + if (FileExists(p)) + return new debSrcRecordParser(p, this); + } + if (FileExists(SourcesURI)) + return new debSrcRecordParser(SourcesURI, this); + return NULL; } /*}}}*/ // SourcesIndex::Describe - Give a descriptive path to the index /*{{{*/ @@ -129,11 +133,15 @@ string debSourcesIndex::Info(const char *Type) const inline string debSourcesIndex::IndexFile(const char *Type) const { string s = URItoFileName(IndexURI(Type)); - string sgzip = s + ".gz"; - if (!FileExists(s) && FileExists(sgzip)) - return sgzip; - else - return s; + + std::vector types = APT::Configuration::getCompressionTypes(); + for (std::vector::const_iterator t = types.begin(); t != types.end(); ++t) + { + string p = s + '.' + *t; + if (FileExists(p)) + return p; + } + return s; } string debSourcesIndex::IndexURI(const char *Type) const @@ -259,11 +267,15 @@ string debPackagesIndex::Info(const char *Type) const inline string debPackagesIndex::IndexFile(const char *Type) const { string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); - string sgzip = s + ".gz"; - if (!FileExists(s) && FileExists(sgzip)) - return sgzip; - else - return s; + + std::vector types = APT::Configuration::getCompressionTypes(); + for (std::vector::const_iterator t = types.begin(); t != types.end(); ++t) + { + string p = s + '.' + *t; + if (FileExists(p)) + return p; + } + return s; } string debPackagesIndex::IndexURI(const char *Type) const { @@ -411,11 +423,15 @@ debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section inline string debTranslationsIndex::IndexFile(const char *Type) const { string s =_config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type)); - string sgzip = s + ".gz"; - if (!FileExists(s) && FileExists(sgzip)) - return sgzip; - else - return s; + + std::vector types = APT::Configuration::getCompressionTypes(); + for (std::vector::const_iterator t = types.begin(); t != types.end(); ++t) + { + string p = s + '.' + *t; + if (FileExists(p)) + return p; + } + return s; } string debTranslationsIndex::IndexURI(const char *Type) const { -- 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') 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') 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