]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
make FORCEBEST work with targeted up/dup
authorMichael Schroeder <mls@suse.de>
Tue, 20 Nov 2012 13:06:08 +0000 (14:06 +0100)
committerMichael Schroeder <mls@suse.de>
Tue, 20 Nov 2012 13:06:08 +0000 (14:06 +0100)
src/problems.c
src/rules.c
src/solver.c

index 5cf42a38f3b5d6ad36152032aeeb3fcf1729dfe2..afb66392e74ee725812f75ce7fc90b28974db1e0 100644 (file)
@@ -441,9 +441,6 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
          return;       /* false alarm */
 
       p = solv->installed->start + (why - solv->updaterules);
-      rr = solv->rules + solv->featurerules + (why - solv->updaterules);
-      if (!rr->p)
-       rr = solv->rules + why;
       if (solv->dupmap_all && solv->rules[why].p != p && solv->decisionmap[p] > 0)
        {
          /* distupgrade case, allow to keep old package */
@@ -453,6 +450,9 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
        }
       if (solv->decisionmap[p] > 0)
        return;         /* false alarm, turned out we can keep the package */
+      rr = solv->rules + solv->featurerules + (why - solv->updaterules);
+      if (!rr->p)
+       rr = solv->rules + why;
       if (rr->w2)
        {
          int mvrp = 0;         /* multi-version replacement */
@@ -496,12 +496,19 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
          queue_push(solutionq, solv->ruletojob.elements[-p - solv->jobrules] + 1);
          return;
        }
+      if (solv->decisionmap[p] > 0)
+       {
+         /* disable best rule by keeping the old package */
+         queue_push(solutionq, SOLVER_SOLUTION_BEST);
+         queue_push(solutionq, p);
+         return;
+       }
       rr = solv->rules + solv->featurerules + (p - solv->installed->start);
       if (!rr->p)
        rr = solv->rules + solv->updaterules + (p - solv->installed->start);
       mvrp = 0;                /* multi-version replacement */
       FOR_RULELITERALS(rp, dp, rr)
-       if (rp > 0 && solv->decisionmap[rp] > 0)
+       if (rp > 0 && solv->decisionmap[rp] > 0 && pool->solvables[rp].repo != solv->installed)
          {
            mvrp = rp;
            if (!(solv->noobsoletes.size && MAPTST(&solv->noobsoletes, rp)))
index 277f771c7d121dfb86bec7d484a3ce1d8a232205..4b50c579cf9fa91ea7fc3cacdd473f93f9bd9758 100644 (file)
@@ -1385,6 +1385,8 @@ solver_addduprules(Solver *solv, Map *addedmap)
                    }
                  if (!ip)
                    solver_addrule(solv, -p, 0);        /* no match, sorry */
+                 else
+                   MAPSET(&solv->dupmap, p);           /* for best rules processing */
                }
            }
          else if (!MAPTST(&solv->dupmap, p))
@@ -2432,6 +2434,37 @@ solver_disablechoicerules(Solver *solv, Rule *r)
     }
 }
 
+static void
+prune_to_update_targets(Solver *solv, Id *cp, Queue *q)
+{
+  int i, j;
+  Id p, *cp2; 
+  for (i = j = 0; i < q->count; i++)
+    {  
+      p = q->elements[i];
+      for (cp2 = cp; *cp2; cp2++)
+        if (*cp2 == p)
+          {
+            q->elements[j++] = p;
+            break;
+          }
+    }
+  queue_truncate(q, j);
+}
+
+static void
+prune_to_dup_packages(Solver *solv, Id p, Queue *q)
+{
+  int i, j;
+  for (i = j = 0; i < q->count; i++)
+    {
+      Id p = q->elements[i];
+      if (MAPTST(&solv->dupmap, p))
+       q->elements[j++] = p;
+    }
+  queue_truncate(q, j);
+}
+
 void
 solver_addbestrules(Solver *solv, int havebestinstalljobs)
 {
@@ -2518,8 +2551,11 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs)
                if (p2 > 0)
                  queue_push(&q, p2);
            }
+         if (solv->update_targets && solv->update_targets->elements[p - installed->start])
+           prune_to_update_targets(solv, solv->update_targets->elements + solv->update_targets->elements[p - installed->start], &q);
+         if (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))
+           prune_to_dup_packages(solv, p, &q);
          /* select best packages, just look at prio and version */
-         oldcnt = q.count;
          policy_filter_unwanted(solv, &q, POLICY_MODE_RECOMMEND);
          if (!q.count)
            continue;   /* orphaned */
@@ -2534,6 +2570,10 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs)
                  FOR_RULELITERALS(p2, pp2, r)
                    if (p2 > 0)
                      queue_push(&q2, p2);
+                 if (solv->update_targets && solv->update_targets->elements[p - installed->start])
+                   prune_to_update_targets(solv, solv->update_targets->elements + solv->update_targets->elements[p - installed->start], &q2);
+                 if (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))
+                   prune_to_dup_packages(solv, p, &q);
                  policy_filter_unwanted(solv, &q2, POLICY_MODE_RECOMMEND);
                  for (j = 0; j < q2.count; j++)
                    queue_pushunique(&q, q2.elements[j]);
index 6e2acba55ae5ef3c4330ff13144c0c23e4f9fcaf..98804427b230eb2bb1b48107df389e7ddc4285ee 100644 (file)
@@ -3237,10 +3237,7 @@ solver_solve(Solver *solv, Queue *job)
     solv->infarchrules = solv->infarchrules_end = solv->nrules;
 
   if (hasdupjob)
-    {
-      solver_addduprules(solv, &addedmap);
-      solver_freedupmaps(solv);        /* no longer needed */
-    }
+    solver_addduprules(solv, &addedmap);
   else
     solv->duprules = solv->duprules_end = solv->nrules;
 
@@ -3249,6 +3246,9 @@ solver_solve(Solver *solv, Queue *job)
   else
     solv->bestrules = solv->bestrules_end = solv->nrules;
 
+  if (hasdupjob)
+    solver_freedupmaps(solv);  /* no longer needed */
+
   if (1)
     solver_addchoicerules(solv);
   else