]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Refactor weak rule handling
authorMichael Schroeder <mls@suse.de>
Tue, 18 Dec 2018 12:57:48 +0000 (13:57 +0100)
committerMichael Schroeder <mls@suse.de>
Tue, 18 Dec 2018 12:57:48 +0000 (13:57 +0100)
src/rules.c
src/solver.c

index df3234167a0b8665c18de50c945717896178048b..e8f8ea0dc8437b750d6d923b60b68d8fc2176574 100644 (file)
@@ -3177,9 +3177,9 @@ solver_addchoicerules(Solver *solv)
   POOL_DEBUG(SOLV_DEBUG_STATS, "choice rule creation took %d ms\n", solv_timems(now));
 }
 
-/* called when a choice rule is disabled by analyze_unsolvable. We also
- * have to disable all other choice rules so that the best packages get
- * picked */
+/* called when a choice rule needs to be disabled by analyze_unsolvable.
+ * We also have to disable all other choice rules so that the best packages
+ * get picked */
 void
 solver_disablechoicerules(Solver *solv, Rule *r)
 {
@@ -3188,6 +3188,7 @@ solver_disablechoicerules(Solver *solv, Rule *r)
   Map m;
   Rule *or;
 
+  solver_disablerule(solv, r);
   or = solv->rules + solv->choicerules_ref[(r - solv->rules) - solv->choicerules];
   map_init(&m, pool->nsolvables);
   FOR_RULELITERALS(p, pp, or)
@@ -3201,7 +3202,7 @@ solver_disablechoicerules(Solver *solv, Rule *r)
       r = solv->rules + rid;
       if (r->d < 0)
        continue;
-      or = solv->rules + solv->choicerules_ref[(r - solv->rules) - solv->choicerules];
+      or = solv->rules + solv->choicerules_ref[rid - solv->choicerules];
       FOR_RULELITERALS(p, pp, or)
         if (p > 0 && MAPTST(&m, p))
          break;
@@ -3442,7 +3443,7 @@ find_obsolete_group(Solver *solv, Id obs, Queue *q)
            continue;
          if ((pool->obsoleteusescolors || pool->implicitobsoleteusescolors) && !pool_colormatch(pool, s2, os))
            continue;
-         obsp2 = os->repo->idarraydata + os->obsoletes; 
+         obsp2 = os->repo->idarraydata + os->obsoletes;
          while ((obs2 = *obsp2++) != 0)
            if (obs2 == obs)
              break;
@@ -3460,7 +3461,7 @@ find_obsolete_group(Solver *solv, Id obs, Queue *q)
            continue;
          if ((pool->obsoleteusescolors || pool->implicitobsoleteusescolors) && !pool_colormatch(pool, s2, os))
            continue;
-         obsp2 = os->repo->idarraydata + os->obsoletes; 
+         obsp2 = os->repo->idarraydata + os->obsoletes;
          while ((obs2 = *obsp2++) != 0)
            if (obs2 == obs)
              break;
@@ -3588,7 +3589,7 @@ for (j = 0; j < qq.count; j++)
   else
     printf("%s\n", pool_solvid2str(pool, qq.elements[j]));
 #endif
-  
+
       if (!qq.count)
        continue;
       /* at least two goups, build rules */
@@ -3696,7 +3697,7 @@ solver_check_brokenorphanrules(Solver *solv, Queue *dq)
   Pool *pool = solv->pool;
   int i;
   Id l, pp;
-  
+
   queue_empty(dq);
   if (!solv->brokenorphanrules)
     return;
index b7729b4be17ce3b16e516f911b18fff4c0a60adf..e020bb13af0fc753e308cdd9364f18907c0a9122 100644 (file)
@@ -894,6 +894,29 @@ analyze_unsolvable_rule(Solver *solv, Rule *r, Queue *weakq, Map *rseen)
     solver_recordproblem(solv, why);
 }
 
+/* fix a problem by disabling one or more weak rules */
+static void
+disable_weakrules(Solver *solv, Queue *weakq)
+{
+  Pool *pool = solv->pool;
+  int i;
+  Id lastweak = 0;
+  for (i = 0; i < weakq->count; i++)
+    if (weakq->elements[i] > lastweak)
+      lastweak = weakq->elements[i];
+  if (lastweak < solv->pkgrules_end && solv->strongrecommends && solv->recommendsruleq && queue_contains(solv->recommendsruleq, lastweak))
+    {
+      disable_recommendsrules(solv, weakq);
+      return;
+    }
+  POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "disabling ");
+  solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, solv->rules + lastweak);
+  /* choice rules need special handling */
+  if (lastweak >= solv->choicerules && lastweak < solv->choicerules_end)
+    solver_disablechoicerules(solv, solv->rules + lastweak);
+  else
+    solver_fixproblem(solv, lastweak);
+}
 
 /*-------------------------------------------------------------------
  *
@@ -924,7 +947,7 @@ analyze_unsolvable(Solver *solv, Rule *cr, int disablerules)
   Map rseen;
   Queue weakq;
   Id pp, v, vv, why;
-  int i, idx;
+  int idx;
   Id *decisionmap = solv->decisionmap;
   int oldproblemcount;
   int oldlearntpoolcount;
@@ -981,28 +1004,12 @@ analyze_unsolvable(Solver *solv, Rule *cr, int disablerules)
 
   if (weakq.count)
     {
-      Id lastweak;
       /* revert problems */
       solv->problems.count = oldproblemcount;
       solv->learnt_pool.count = oldlearntpoolcount;
-      /* find last weak */
-      lastweak = 0;
-      for (i = 0; i < weakq.count; i++)
-       if (weakq.elements[i] > lastweak)
-         lastweak = weakq.elements[i];
-      if (lastweak < solv->pkgrules_end && solv->strongrecommends && solv->recommendsruleq && queue_contains(solv->recommendsruleq, lastweak))
-       {
-         disable_recommendsrules(solv, &weakq);
-         queue_free(&weakq);
-         solver_reset(solv);
-         return 0;
-       }
+      /* disable some weak rules */
+      disable_weakrules(solv, &weakq);
       queue_free(&weakq);
-      POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "disabling ");
-      solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, solv->rules + lastweak);
-      if (lastweak >= solv->choicerules && lastweak < solv->choicerules_end)
-       solver_disablechoicerules(solv, solv->rules + lastweak);
-      solver_fixproblem(solv, lastweak);
       solver_reset(solv);
       return 0;
     }