support "pooljobs", fixed jobs set in the pool
authorMichael Schroeder <mls@suse.de>
Fri, 11 Jan 2013 12:54:53 +0000 (13:54 +0100)
committerMichael Schroeder <mls@suse.de>
Fri, 11 Jan 2013 12:54:53 +0000 (13:54 +0100)
Those are normally jobs like USERINSTALLED or NOOBSOLETES.

bindings/solv.i
src/pool.c
src/pool.h
src/problems.c
src/problems.h
src/solver.c
src/solver.h
src/solverdebug.c

index 3273b349d885792c45c09c4a53683e89cdc3f2d1..16564ff139b185db1b5326843ffba3aa256bacc7 100644 (file)
@@ -1329,6 +1329,49 @@ typedef struct {
     sel->flags = selection_make($self, &sel->q, name, flags);
     return sel;
   }
+
+  void setpooljobs_helper(Queue jobs) {
+    queue_free(&$self->pooljobs);
+    queue_init_clone(&$self->pooljobs, &jobs);
+  }
+  %typemap(out) Queue getpooljobs Queue2Array(Job *, 2, new_Job(arg1, id, idp[1]));
+  %newobject getpooljobs;
+  Queue getpooljobs() {
+    Queue q;
+    queue_init_clone(&q, &$self->pooljobs);
+    return q;
+  }
+
+#if defined(SWIGPYTHON)
+  %pythoncode {
+    def setpooljobs(self, jobs):
+      j = []
+      for job in jobs: j += [job.how, job.what]
+      self.setpooljobs_helper(j)
+  }
+#endif
+#if defined(SWIGPERL)
+  %perlcode {
+    sub solv::Solver::setpooljobs {
+      my ($self, $jobs) = @_;
+      my @j = map {($_->{'how'}, $_->{'what'})} @$jobs;
+      return $self->setpooljobs_helper(\@j);
+    }
+  }
+#endif
+#if defined(SWIGRUBY)
+%init %{
+rb_eval_string(
+    "class Solv::Pool\n"
+    "  def setpooljobs(jobs)\n"
+    "    jl = []\n"
+    "    jobs.each do |j| ; jl << j.how << j.what ; end\n"
+    "    setpooljobs_helper(jl)\n"
+    "  end\n"
+    "end\n"
+  );
+%}
+#endif
 }
 
 %extend Repo {
@@ -2466,6 +2509,7 @@ typedef struct {
   static const int SOLVER_RULE_LEARNT = SOLVER_RULE_LEARNT;
 
   static const int SOLVER_SOLUTION_JOB = SOLVER_SOLUTION_JOB;
+  static const int SOLVER_SOLUTION_POOLJOB = SOLVER_SOLUTION_POOLJOB;
   static const int SOLVER_SOLUTION_INFARCH = SOLVER_SOLUTION_INFARCH;
   static const int SOLVER_SOLUTION_DISTUPGRADE = SOLVER_SOLUTION_DISTUPGRADE;
   static const int SOLVER_SOLUTION_BEST = SOLVER_SOLUTION_BEST;
index 0f7c9287badcf5cead81deb5eb4511afb1b7af28..d8eb0402d3bf23ef6edf6962125a43b89207f495 100644 (file)
@@ -103,6 +103,7 @@ pool_free(Pool *pool)
   solv_free(pool->rels);
   pool_setvendorclasses(pool, 0);
   queue_free(&pool->vendormap);
+  queue_free(&pool->pooljobs);
   for (i = 0; i < POOL_TMPSPACEBUF; i++)
     solv_free(pool->tmpspace.buf[i]);
   for (i = 0; i < pool->nlanguages; i++)
index cb838007f2b8a2dbeb355685379ecfa34d781cc4..97224e08acfbc7214a885c69303a9440b47bdea5 100644 (file)
@@ -119,6 +119,8 @@ struct _Pool {
   /* search position */
   Datapos pos;
 
+  Queue pooljobs;              /* fixed jobs, like USERINSTALLED/NOOBSOLETES */
+
 #ifdef LIBSOLV_INTERNAL
   /* flags to tell the library how the installed package manager works */
   int promoteepoch;            /* true: missing epoch is replaced by epoch of dependency   */
index fe3f2a243eb1ca9d4eb506b3fb7bb06cba5d115a..11db5feb7c412996e5f92d4646bd6c9e73ee9b3b 100644 (file)
@@ -260,7 +260,7 @@ refine_suggestion(Solver *solv, Id *problem, Id sug, Queue *refined, int essenti
                nupdate++;
              else
                {
-                 if (!essentialok && (solv->job.elements[-v -1] & SOLVER_ESSENTIAL) != 0)
+                 if (!essentialok && (solv->job.elements[-v - 1] & SOLVER_ESSENTIAL) != 0)
                    continue;   /* not that one! */
                  njob++;
                }
@@ -382,8 +382,17 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
   Pool *pool = solv->pool;
   if (why < 0)
     {
-      queue_push(solutionq, 0);
-      queue_push(solutionq, -why);
+      why = -why;
+      if (why < solv->pooljobcnt)
+       {
+         queue_push(solutionq, SOLVER_SOLUTION_POOLJOB);
+         queue_push(solutionq, why);
+       }
+      else
+       {
+         queue_push(solutionq, SOLVER_SOLUTION_JOB);
+         queue_push(solutionq, why - solv->pooljobcnt);
+       }
       return;
     }
   if (why >= solv->infarchrules && why < solv->infarchrules_end)
@@ -775,6 +784,8 @@ solver_solutionelement_extrajobflags(Solver *solv, Id problem, Id solution)
  *    -> add (SOLVER_INSTALL|SOLVER_SOLVABLE, rp) to the job
  *    SOLVER_SOLUTION_JOB           jobidx
  *    -> remove job (jobidx - 1, jobidx) from job queue
+ *    SOLVER_SOLUTION_POOLJOB       jobidx
+ *    -> remove job (jobidx - 1, jobidx) from pool job queue
  *    pkgid (> 0)                   0
  *    -> add (SOLVER_ERASE|SOLVER_SOLVABLE, p) to the job
  *    pkgid (> 0)                   pkgid (> 0)
@@ -807,6 +818,12 @@ solver_take_solutionelement(Solver *solv, Id p, Id rp, Id extrajobflags, Queue *
 {
   int i;
 
+  if (p == SOLVER_SOLUTION_POOLJOB)
+    {
+      solv->pool->pooljobs.elements[rp - 1] = SOLVER_NOOP;
+      solv->pool->pooljobs.elements[rp] = 0;
+      return;
+    }
   if (p == SOLVER_SOLUTION_JOB)
     {
       job->elements[rp - 1] = SOLVER_NOOP;
index cb37139488037c47503d505e908b593cad9c360c..4f5021f9fc00b1e8e1b5c8511a836873a2e91b18 100644 (file)
@@ -24,6 +24,7 @@ struct _Solver;
 #define SOLVER_SOLUTION_DISTUPGRADE     (-1)
 #define SOLVER_SOLUTION_INFARCH         (-2)
 #define SOLVER_SOLUTION_BEST            (-3)
+#define SOLVER_SOLUTION_POOLJOB         (-4)
 
 void solver_disableproblem(struct _Solver *solv, Id v);
 void solver_enableproblem(struct _Solver *solv, Id v);
index 76680ceacf4ad550cdf51131d76a4fe7c3f578e7..2f248398897b936900cbc06e5dcab6b97997c9ee 100644 (file)
@@ -2874,6 +2874,13 @@ solver_solve(Solver *solv, Queue *job)
   /* remember job */
   queue_free(&solv->job);
   queue_init_clone(&solv->job, job);
+  solv->pooljobcnt = pool->pooljobs.count;
+  if (pool->pooljobs.count)
+    {
+      queue_insertn(&solv->job, 0, pool->pooljobs.count);
+      memcpy(solv->job.elements, pool->pooljobs.elements, pool->pooljobs.count * sizeof(Id));
+    }
+  job = &solv->job;
 
   /* free old stuff */
   if (solv->update_targets)
@@ -3177,6 +3184,8 @@ solver_solve(Solver *solv, Queue *job)
     {
       oldnrules = solv->nrules;
 
+      if (i && i == solv->pooljobcnt)
+        POOL_DEBUG(SOLV_DEBUG_JOB, "end of pool jobs\n");
       how = job->elements[i];
       what = job->elements[i + 1];
       weak = how & SOLVER_WEAK;
@@ -3346,10 +3355,10 @@ solver_solve(Solver *solv, Queue *job)
        {
          int j;
          if (solv->nrules == oldnrules)
-           POOL_DEBUG(SOLV_DEBUG_JOB, " - no rule created\n");
+           POOL_DEBUG(SOLV_DEBUG_JOB, "  - no rule created\n");
          for (j = oldnrules; j < solv->nrules; j++)
            {
-             POOL_DEBUG(SOLV_DEBUG_JOB, " - job ");
+             POOL_DEBUG(SOLV_DEBUG_JOB, "  - job ");
              solver_printrule(solv, SOLV_DEBUG_JOB, solv->rules + j);
            }
        }
index dc7377fcc0433b7e8310f3b5134bcdc0bfa9e2a8..a134718675df0c670bf1452f5901be7567b15e7e 100644 (file)
@@ -82,6 +82,8 @@ struct _Solver {
    */
   UpdateCandidateCb   updateCandidateCb;
 
+  int pooljobcnt;              /* number of pooljob entries in job queue */
+
 #ifdef LIBSOLV_INTERNAL
   Repo *installed;                     /* copy of pool->installed */
   
index 58785f76fddffc8db2f27b14fbeac6cb54b2d05e..666401f65ec3182c0be2d727faaefd2c68fb0245 100644 (file)
@@ -656,9 +656,11 @@ solver_printsolution(Solver *solv, Id problem, Id solution)
   element = 0;
   while ((element = solver_next_solutionelement(solv, problem, solution, element, &p, &rp)) != 0)
     {
-      if (p == SOLVER_SOLUTION_JOB)
+      if (p == SOLVER_SOLUTION_JOB || p == SOLVER_SOLUTION_POOLJOB)
        {
          /* job, rp is index into job queue */
+         if (p == SOLVER_SOLUTION_JOB)
+           rp += solv->pooljobcnt;
          how = solv->job.elements[rp - 1];
          what = solv->job.elements[rp];
          select = how & SOLVER_SELECTMASK;
@@ -1042,10 +1044,13 @@ const char *
 solver_solutionelement2str(Solver *solv, Id p, Id rp)
 {
   Pool *pool = solv->pool;
-  if (p == SOLVER_SOLUTION_JOB)
+  if (p == SOLVER_SOLUTION_JOB || p == SOLVER_SOLUTION_POOLJOB)
     {
-      Id how = solv->job.elements[rp - 1];
-      Id what = solv->job.elements[rp];
+      Id how, what;
+      if (p == SOLVER_SOLUTION_JOB)
+       rp += solv->pooljobcnt;
+      how = solv->job.elements[rp - 1];
+      what = solv->job.elements[rp];
       return pool_tmpjoin(pool, "do not ask to ", pool_job2str(pool, how, what, 0), 0);
     }
   else if (p == SOLVER_SOLUTION_INFARCH)