Bladeren bron

edsp: use an ID mapping for the internal solver

Currently an EDSP solver gets send basically all versions which means
the absolute count is the same, but that might not be true forever (and
with the skipping of rc-only versions it kinda is already) and even if
it were true, segfaulting on bad input seems wrong.
David Kalnischkies 10 jaren geleden
bovenliggende
commit
307d9eb2d1

+ 7 - 6
apt-pkg/edsp.cc

@@ -17,6 +17,7 @@
 #include <apt-pkg/edsp.h>
 #include <apt-pkg/edsp.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
+#include <apt-pkg/pkgsystem.h>
 
 
 #include <ctype.h>
 #include <ctype.h>
 #include <stddef.h>
 #include <stddef.h>
@@ -878,20 +879,20 @@ bool EDSP::WriteSolution(pkgDepCache &Cache, FILE* output)
    {
    {
       if (Cache[Pkg].Delete() == true)
       if (Cache[Pkg].Delete() == true)
       {
       {
-	 fprintf(output, "Remove: %d\n", Pkg.CurrentVer()->ID);
+	 fprintf(output, "Remove: %d\n", _system->GetVersionMapping(Pkg.CurrentVer()->ID));
 	 if (Debug == true)
 	 if (Debug == true)
 	    fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Pkg.CurrentVer().VerStr());
 	    fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Pkg.CurrentVer().VerStr());
       }
       }
       else if (Cache[Pkg].NewInstall() == true || Cache[Pkg].Upgrade() == true)
       else if (Cache[Pkg].NewInstall() == true || Cache[Pkg].Upgrade() == true)
       {
       {
 	 pkgCache::VerIterator const CandVer = Cache.GetCandidateVersion(Pkg);
 	 pkgCache::VerIterator const CandVer = Cache.GetCandidateVersion(Pkg);
-	 fprintf(output, "Install: %d\n", CandVer->ID);
+	 fprintf(output, "Install: %d\n", _system->GetVersionMapping(CandVer->ID));
 	 if (Debug == true)
 	 if (Debug == true)
 	    fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), CandVer.VerStr());
 	    fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), CandVer.VerStr());
       }
       }
       else if (Cache[Pkg].Garbage == true)
       else if (Cache[Pkg].Garbage == true)
       {
       {
-	 fprintf(output, "Autoremove: %d\n", Pkg.CurrentVer()->ID);
+	 fprintf(output, "Autoremove: %d\n", _system->GetVersionMapping(Pkg.CurrentVer()->ID));
 	 if (Debug == true)
 	 if (Debug == true)
 	    fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Pkg.CurrentVer().VerStr());
 	    fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Pkg.CurrentVer().VerStr());
       }
       }
@@ -910,11 +911,11 @@ bool EDSP::WriteSolution(pkgDepCache &Cache, FileFd &output)
    {
    {
       std::string action;
       std::string action;
       if (Cache[Pkg].Delete() == true)
       if (Cache[Pkg].Delete() == true)
-	 WriteOkay(Okay, output, "Remove: ", Pkg.CurrentVer()->ID, "\n");
+	 WriteOkay(Okay, output, "Remove: ", _system->GetVersionMapping(Pkg.CurrentVer()->ID), "\n");
       else if (Cache[Pkg].NewInstall() == true || Cache[Pkg].Upgrade() == true)
       else if (Cache[Pkg].NewInstall() == true || Cache[Pkg].Upgrade() == true)
-	 WriteOkay(Okay, output, "Install: ", Cache.GetCandidateVersion(Pkg)->ID, "\n");
+	 WriteOkay(Okay, output, "Install: ", _system->GetVersionMapping(Cache.GetCandidateVersion(Pkg)->ID), "\n");
       else if (Cache[Pkg].Garbage == true)
       else if (Cache[Pkg].Garbage == true)
-	 WriteOkay(Okay, output, "Autoremove: ", Pkg.CurrentVer()->ID, "\n");
+	 WriteOkay(Okay, output, "Autoremove: ", _system->GetVersionMapping(Pkg.CurrentVer()->ID), "\n");
       else
       else
 	 continue;
 	 continue;
 
 

+ 2 - 1
apt-pkg/edsp/edsplistparser.cc

@@ -19,6 +19,7 @@
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/tagfile.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
+#include <apt-pkg/pkgsystem.h>
 
 
 									/*}}}*/
 									/*}}}*/
 
 
@@ -47,7 +48,7 @@ edspListParser::edspListParser(FileFd *File) : debListParser(File), d(new edspLi
 // ListParser::NewVersion - Fill in the version structure		/*{{{*/
 // ListParser::NewVersion - Fill in the version structure		/*{{{*/
 bool edspListParser::NewVersion(pkgCache::VerIterator &Ver)
 bool edspListParser::NewVersion(pkgCache::VerIterator &Ver)
 {
 {
-   Ver->ID = Section.FindI("APT-ID", Ver->ID);
+   _system->SetVersionMapping(Ver->ID, Section.FindI("APT-ID", Ver->ID));
    return debListParser::NewVersion(Ver);
    return debListParser::NewVersion(Ver);
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 23 - 1
apt-pkg/pkgsystem.cc

@@ -16,6 +16,7 @@
 #include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
 
 
+#include <map>
 #include <cassert>
 #include <cassert>
 #include <cstring>
 #include <cstring>
 									/*}}}*/
 									/*}}}*/
@@ -25,11 +26,19 @@ static pkgSystem *SysList[10];
 pkgSystem **pkgSystem::GlobalList = SysList;
 pkgSystem **pkgSystem::GlobalList = SysList;
 unsigned long pkgSystem::GlobalListLen = 0;
 unsigned long pkgSystem::GlobalListLen = 0;
 
 
+class APT_HIDDEN pkgSystemPrivate					/*{{{*/
+{
+public:
+   typedef decltype(pkgCache::Version::ID) idtype;
+   std::map<idtype,idtype> idmap;
+   pkgSystemPrivate() {}
+};
+									/*}}}*/
 // System::pkgSystem - Constructor					/*{{{*/
 // System::pkgSystem - Constructor					/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Add it to the global list.. */
 /* Add it to the global list.. */
 pkgSystem::pkgSystem(char const * const label, pkgVersioningSystem * const vs) :
 pkgSystem::pkgSystem(char const * const label, pkgVersioningSystem * const vs) :
-   Label(label), VS(vs), d(NULL)
+   Label(label), VS(vs), d(new pkgSystemPrivate())
 {
 {
    assert(GlobalListLen < sizeof(SysList)/sizeof(*SysList));
    assert(GlobalListLen < sizeof(SysList)/sizeof(*SysList));
    SysList[GlobalListLen] = this;
    SysList[GlobalListLen] = this;
@@ -63,5 +72,18 @@ std::vector<std::string> pkgSystem::ArchitecturesSupported() const	/*{{{*/
    return {};
    return {};
 }
 }
 									/*}}}*/
 									/*}}}*/
+// pkgSystem::Set/GetVersionMapping - for internal/external communcation/*{{{*/
+void pkgSystem::SetVersionMapping(map_id_t const in, map_id_t const out)
+{
+   if (in == out)
+      return;
+   d->idmap.emplace(in, out);
+}
+map_id_t pkgSystem::GetVersionMapping(map_id_t const in) const
+{
+   auto const o = d->idmap.find(in);
+   return (o == d->idmap.end()) ? in : o->second;
+}
+									/*}}}*/
 
 
 pkgSystem::~pkgSystem() {}
 pkgSystem::~pkgSystem() {}

+ 5 - 1
apt-pkg/pkgsystem.h

@@ -51,6 +51,7 @@ class pkgVersioningSystem;
 class Configuration;
 class Configuration;
 class pkgIndexFile;
 class pkgIndexFile;
 
 
+class pkgSystemPrivate;
 class pkgSystem
 class pkgSystem
 {
 {
    public:
    public:
@@ -114,10 +115,13 @@ class pkgSystem
     */
     */
    std::vector<std::string> ArchitecturesSupported() const;
    std::vector<std::string> ArchitecturesSupported() const;
 
 
+   APT_HIDDEN void SetVersionMapping(map_id_t const in, map_id_t const out);
+   APT_HIDDEN map_id_t GetVersionMapping(map_id_t const in) const;
+
    pkgSystem(char const * const Label, pkgVersioningSystem * const VS);
    pkgSystem(char const * const Label, pkgVersioningSystem * const VS);
    virtual ~pkgSystem();
    virtual ~pkgSystem();
    private:
    private:
-   void * const d;
+   pkgSystemPrivate * const d;
 };
 };
 
 
 // The environment we are operating in.
 // The environment we are operating in.

+ 5 - 0
test/integration/test-external-dependency-solver-protocol

@@ -153,6 +153,11 @@ else
 	cat solver.result
 	cat solver.result
 	msgfail
 	msgfail
 fi
 fi
+testsuccess grep '^APT-ID: 1$' "$APT_EDSP_DUMP_FILENAME"
+sed -i -e 's#^APT-ID: 1$#APT-ID: 10000#' "$APT_EDSP_DUMP_FILENAME"
+cat "$APT_EDSP_DUMP_FILENAME" | aptinternalsolver > solver.result 2>&1 || true
+testsuccessequal 'Message: Done
+' tail -n2 solver.result
 rm -f "$APT_EDSP_DUMP_FILENAME"
 rm -f "$APT_EDSP_DUMP_FILENAME"
 
 
 testsuccess aptinternalsolver scenario
 testsuccess aptinternalsolver scenario