]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Also disable the corresponding forcebest rule when disabling a job
authorMichael Schroeder <mls@suse.de>
Thu, 2 Nov 2017 11:51:49 +0000 (12:51 +0100)
committerMichael Schroeder <mls@suse.de>
Thu, 2 Nov 2017 11:51:49 +0000 (12:51 +0100)
src/problems.c
src/rules.c
src/solver.c
src/solver.h
test/testcases/forcebest/forcebest_in.t

index 2ffb6f9d41dfba1a4246eabd5dcc686536073e3d..2b5ef53aebf0978654b64feb8dd23bbc515b0f76 100644 (file)
@@ -35,7 +35,6 @@
 void
 solver_disableproblem(Solver *solv, Id v)
 {
-  Rule *r;
   int i;
   Id *jp;
 
@@ -76,9 +75,19 @@ solver_disableproblem(Solver *solv, Id v)
     }
   v = -(v + 1);
   jp = solv->ruletojob.elements;
-  for (i = solv->jobrules, r = solv->rules + i; i < solv->jobrules_end; i++, r++, jp++)
+  if (solv->bestrules_pkg)
+    {
+      int ni = solv->bestrules_end - solv->bestrules;
+      for (i = 0; i < ni; i++)
+       {
+         int j = solv->bestrules_pkg[i];
+         if (j < 0 && jp[-j - solv->jobrules] == v)
+           solver_disablerule(solv, solv->rules + solv->bestrules + i);
+       }
+    }
+  for (i = solv->jobrules; i < solv->jobrules_end; i++, jp++)
     if (*jp == v)
-      solver_disablerule(solv, r);
+      solver_disablerule(solv, solv->rules + i);
 }
 
 /*-------------------------------------------------------------------
@@ -133,9 +142,19 @@ solver_enableproblem(Solver *solv, Id v)
     }
   v = -(v + 1);
   jp = solv->ruletojob.elements;
-  for (i = solv->jobrules, r = solv->rules + i; i < solv->jobrules_end; i++, r++, jp++)
+  if (solv->bestrules_pkg)
+    {
+      int ni = solv->bestrules_end - solv->bestrules;
+      for (i = 0; i < ni; i++)
+       {
+         int j = solv->bestrules_pkg[i];
+         if (j < 0 && jp[-j - solv->jobrules] == v)
+           solver_enablerule(solv, solv->rules + solv->bestrules + i);
+       }
+    }
+  for (i = solv->jobrules; i < solv->jobrules_end; i++, jp++)
     if (*jp == v)
-      solver_enablerule(solv, r);
+      solver_enablerule(solv, solv->rules + i);
 }
 
 
index 2e3444b41b00f11ddaa4448de9af73cb2f1b2825..261e8595a2890bcb71097f5a8e4ee2dee78fc7e6 100644 (file)
@@ -1466,7 +1466,7 @@ disableupdaterule(Solver *solv, Id p)
     {
       int i, ni;
       ni = solv->bestrules_end - solv->bestrules;
-      for (i = 0; i < ni; i++)
+      for (i = solv->bestrules_up - solv->bestrules; i < ni; i++)
        if (solv->bestrules_pkg[i] == p)
          solver_disablerule(solv, solv->rules + solv->bestrules + i);
     }
@@ -1509,7 +1509,7 @@ reenableupdaterule(Solver *solv, Id p)
     {
       int i, ni;
       ni = solv->bestrules_end - solv->bestrules;
-      for (i = 0; i < ni; i++)
+      for (i = solv->bestrules_up - solv->bestrules; i < ni; i++)
        if (solv->bestrules_pkg[i] == p)
          solver_enablerule(solv, solv->rules + solv->bestrules + i);
     }
@@ -3257,36 +3257,47 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs)
     {
       for (i = 0; i < solv->job.count; i += 2)
        {
-         if ((solv->job.elements[i] & (SOLVER_JOBMASK | SOLVER_FORCEBEST)) == (SOLVER_INSTALL | SOLVER_FORCEBEST))
+         Id how = solv->job.elements[i];
+         if ((how & (SOLVER_JOBMASK | SOLVER_FORCEBEST)) == (SOLVER_INSTALL | SOLVER_FORCEBEST))
            {
              int j;
              Id p2, pp2;
              for (j = 0; j < solv->ruletojob.count; j++)
-               if (solv->ruletojob.elements[j] == i)
-                 break;
-             if (j == solv->ruletojob.count)
-               continue;
-             r = solv->rules + solv->jobrules + j;
-             queue_empty(&q);
-             FOR_RULELITERALS(p2, pp2, r)
-               if (p2 > 0)
-                 queue_push(&q, p2);
-             if (!q.count)
-               continue;       /* orphaned */
-             /* select best packages, just look at prio and version */
-             oldcnt = q.count;
-             policy_filter_unwanted(solv, &q, POLICY_MODE_RECOMMEND);
-             if (q.count == oldcnt)
-               continue;       /* nothing filtered */
-             p2 = queue_shift(&q);
-             if (q.count < 2)
-               solver_addrule(solv, p2, q.count ? q.elements[0] : 0, 0);
-             else
-               solver_addrule(solv, p2, 0, pool_queuetowhatprovides(pool, &q));
-             queue_push(&r2pkg, -(solv->jobrules + j));
+               {
+                 if (solv->ruletojob.elements[j] != i)
+                   continue;
+                 r = solv->rules + solv->jobrules + j;
+                 queue_empty(&q);
+                 queue_empty(&q2);
+                 FOR_RULELITERALS(p2, pp2, r)
+                   {
+                     if (p2 > 0)
+                       queue_push(&q, p2);
+                     else if (p2 < 0)
+                       queue_push(&q2, p2);
+                   }
+                 if (!q.count)
+                   continue;   /* orphaned */
+                 /* select best packages, just look at prio and version */
+                 oldcnt = q.count;
+                 policy_filter_unwanted(solv, &q, POLICY_MODE_RECOMMEND);
+                 if (q.count == oldcnt)
+                   continue;   /* nothing filtered */
+                 if (q2.count)
+                   queue_insertn(&q, 0, q2.count, q2.elements);
+                 p2 = queue_shift(&q);
+                 if (q.count < 2)
+                   solver_addrule(solv, p2, q.count ? q.elements[0] : 0, 0);
+                 else
+                   solver_addrule(solv, p2, 0, pool_queuetowhatprovides(pool, &q));
+                 if ((how & SOLVER_WEAK) != 0)
+                   queue_push(&solv->weakruleq, solv->nrules - 1);
+                 queue_push(&r2pkg, -(solv->jobrules + j));
+               }
            }
        }
     }
+  solv->bestrules_up = solv->nrules;
 
   if (installed && (solv->bestupdatemap_all || solv->bestupdatemap.size))
     {
index b9d91d288cbe129d2b49418557f274f04ae1bd53..1339a5bbdf619453e76b0138d59316172b3e1b6d 100644 (file)
@@ -288,6 +288,8 @@ makeruledecisions(Solver *solv)
              POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "conflict with system solvable, disabling rule #%d\n", ri);
              if  (ri >= solv->jobrules && ri < solv->jobrules_end)
                v = -(solv->ruletojob.elements[ri - solv->jobrules] + 1);
+             else if (ri >= solv->bestrules && ri < solv->bestrules_up && solv->bestrules_pkg[ri - solv->bestrules] < 0)
+               v = -(solv->ruletojob.elements[-solv->bestrules_pkg[ri - solv->bestrules] - solv->jobrules] + 1);
              else
                v = ri;
              queue_push(&solv->problems, v);
@@ -329,6 +331,8 @@ makeruledecisions(Solver *solv)
              POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "conflict with pkg rule, disabling rule #%d\n", ri);
              if (ri >= solv->jobrules && ri < solv->jobrules_end)
                v = -(solv->ruletojob.elements[ri - solv->jobrules] + 1);
+             else if (ri >= solv->bestrules && ri < solv->bestrules_up && solv->bestrules_pkg[ri - solv->bestrules] < 0)
+               v = -(solv->ruletojob.elements[-solv->bestrules_pkg[ri - solv->bestrules] - solv->jobrules] + 1);
              else
                v = ri;
              queue_push(&solv->problems, v);
@@ -383,9 +387,12 @@ makeruledecisions(Solver *solv)
              POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, " - disabling rule #%d\n", i);
              solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, solv->rules + i);
                
-             v = i;
              if (i >= solv->jobrules && i < solv->jobrules_end)
                v = -(solv->ruletojob.elements[i - solv->jobrules] + 1);
+             else if (i >= solv->bestrules && i < solv->bestrules_up && solv->bestrules_pkg[i - solv->bestrules] < 0)
+               v = -(solv->ruletojob.elements[-solv->bestrules_pkg[i - solv->bestrules] - solv->jobrules] + 1);
+             else
+               v = i;
              queue_push(&solv->problems, v);
            }
          queue_push(&solv->problems, 0);
@@ -448,6 +455,8 @@ makeruledecisions(Solver *solv)
 
          if (ri >= solv->jobrules && ri < solv->jobrules_end)
            v = -(solv->ruletojob.elements[ri - solv->jobrules] + 1);
+         else if (ri >= solv->bestrules && ri < solv->bestrules_up && solv->bestrules_pkg[ri - solv->bestrules] < 0)
+           v = -(solv->ruletojob.elements[-solv->bestrules_pkg[ri - solv->bestrules] - solv->jobrules] + 1);
          else
            v = ri;
          solver_disableproblem(solv, v);
@@ -1019,6 +1028,8 @@ analyze_unsolvable_rule(Solver *solv, Rule *r, Queue *weakq, Map *rseen)
   /* turn rule into problem */
   if (why >= solv->jobrules && why < solv->jobrules_end)
     why = -(solv->ruletojob.elements[why - solv->jobrules] + 1);
+  else if (why >= solv->bestrules && why < solv->bestrules_up && solv->bestrules_pkg[why - solv->bestrules] < 0)
+    why = -(solv->ruletojob.elements[-solv->bestrules_pkg[why - solv->bestrules] - solv->jobrules] + 1);
   /* normalize dup/infarch rules */
   if (why > solv->infarchrules && why < solv->infarchrules_end)
     {
@@ -3494,7 +3505,6 @@ solver_solve(Solver *solv, Queue *job)
     deduceq2addedmap(solv, &addedmap);
   if (solv->nrules != initialnrules)
     solver_shrinkrules(solv, initialnrules);
-  solv->nrules = initialnrules;
   solv->lastpkgrule = 0;
   solv->pkgrules_end = 0;
 
@@ -4021,18 +4031,7 @@ solver_solve(Solver *solv, Queue *job)
 
   /* now create infarch and dup rules */
   if (!solv->noinfarchcheck)
-    {
-      solver_addinfarchrules(solv, &addedmap);
-#if 0
-      if (pool->implicitobsoleteusescolors)
-       {
-         /* currently doesn't work well with infarch rules, so make
-           * them weak */
-         for (i = solv->infarchrules; i < solv->infarchrules_end; i++)
-           queue_push(&solv->weakruleq, i);
-       }
-#endif
-    }
+    solver_addinfarchrules(solv, &addedmap);
   else
     solv->infarchrules = solv->infarchrules_end = solv->nrules;
 
@@ -4049,7 +4048,7 @@ solver_solve(Solver *solv, Queue *job)
   if (solv->bestupdatemap_all || solv->bestupdatemap.size || hasbestinstalljob)
     solver_addbestrules(solv, hasbestinstalljob);
   else
-    solv->bestrules = solv->bestrules_end = solv->nrules;
+    solv->bestrules = solv->bestrules_end = solv->bestrules_up = solv->nrules;
 
   if (needduprules)
     solver_freedupmaps(solv);  /* no longer needed */
index 1b85fb34fd21de992d7922645e9f84be642604fd..ebb2232bb0a3e11aa415194e4616d7962494687a 100644 (file)
@@ -68,6 +68,7 @@ struct _Solver {
   Id duprules_end;
 
   Id bestrules;                                /* rules from SOLVER_FORCEBEST */
+  Id bestrules_up;                     /* update rule part starts here*/
   Id bestrules_end;
   Id *bestrules_pkg;
 
index aaf2aa1db49b9f86c1913dd607eefe473eadfdb5..93165c8b6011b8b798e1983af38ec312127f8a67 100644 (file)
@@ -11,19 +11,15 @@ system i686 rpm system
 
 job install name A [forcebest]
 result transaction,problems <inline>
-#>erase D-1-1.noarch@system
-#>install A-3-1.noarch@available
 #>problem 1210fdfb info package D-1-1.noarch conflicts with A = 3-1 provided by A-3-1.noarch
 #>problem 1210fdfb solution 0d75a914 erase D-1-1.noarch@system
-#>problem 1210fdfb solution d85f7c4e deljob install name A [forcebest]
+#>problem 1210fdfb solution ee74e60f deljob install name A [forcebest]
 
 # currently bestobeypolicy is a noop for install jobs
 nextjob
 solverflags bestobeypolicy
 job install name A [forcebest]
 result transaction,problems <inline>
-#>erase D-1-1.noarch@system
-#>install A-3-1.noarch@available
 #>problem 1210fdfb info package D-1-1.noarch conflicts with A = 3-1 provided by A-3-1.noarch
 #>problem 1210fdfb solution 0d75a914 erase D-1-1.noarch@system
-#>problem 1210fdfb solution d85f7c4e deljob install name A [forcebest]
+#>problem 1210fdfb solution ee74e60f deljob install name A [forcebest]