]> git.saurik.com Git - apt.git/commitdiff
store source name and version in binary cache
authorDavid Kalnischkies <david@kalnischkies.de>
Fri, 20 Jun 2014 17:34:40 +0000 (19:34 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Fri, 26 Sep 2014 23:45:37 +0000 (01:45 +0200)
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
apt-pkg/deb/deblistparser.cc
apt-pkg/deb/dpkgpm.cc
apt-pkg/edsp.cc
apt-pkg/pkgcache.h
cmdline/apt-cache.cc
cmdline/apt-get.cc

index 12a03eb07a21e145480f420bc9d9b4a24c6f0284..b0c02d4a20f591e261101d9ce5978e73e3941052 100644 (file)
@@ -215,6 +215,12 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
        // 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";
index 9919d2036b5b0f7ada9e73368397c461ac9fa65a..103b126de05b58b9316a9835bc8aad8a9752797e 100644 (file)
@@ -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
index a5c05d5eadcb93f668d7a13513d027bf2a9bd67c..95fae9a28cf312f9e67ec1b15471e064078267c4 100644 (file)
@@ -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
index 0d0418e0633c52c191dde8d4b4a6f38448db2465..2ba914b16ee8e14d7655de1d644c74da2c2aca3c 100644 (file)
@@ -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)
index 4284a318c6969a4e81cff983336fc4e35852f55f..6a89eabd72c3d2ad058db082844341080246f0d5 100644 (file)
@@ -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 */
index 5a5dde08814608c9f0f9e596243982b171473682..0f4f7e1ce1e9ef30a9ce9bd716e9c46bd5263988 100644 (file)
@@ -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)
index aed1beb4df6c6009fb51b2f02d182cc5c86ccce5..a5cafc39dfa71a9e761fa83715f775276f9bc71f 100644 (file)
@@ -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);