]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
- do not set up unneeded choice rules
authorMichael Schroeder <mls@suse.de>
Mon, 27 Jul 2009 09:51:00 +0000 (11:51 +0200)
committerMichael Schroeder <mls@suse.de>
Mon, 27 Jul 2009 09:51:00 +0000 (11:51 +0200)
examples/solv.c
src/rules.c
src/solver.c

index 52a965e2ccaec4355e5da286d5bd1bab72f1a43b..c53dca958384ed7eb0b8441f60bfeb326378b1ce 100644 (file)
@@ -2001,6 +2001,7 @@ usage(int r)
   fprintf(stderr, "    repos:       list enabled repositories\n");
   fprintf(stderr, "    search:      search name/summary/description\n");
   fprintf(stderr, "    update:      update installed packages\n");
+  fprintf(stderr, "    verify:      check dependencies of installed packages\n");
   fprintf(stderr, "\n");
   exit(r);
 }
index 0069e758855b0a6959f2f7c13664f8026bffa20e..225c4d8abbc503d3af00e776689b995d83aa6546 100644 (file)
@@ -1775,9 +1775,10 @@ void
 addchoicerules(Solver *solv)
 {
   Pool *pool = solv->pool;
+  Map m;
   Rule *r;
-  Queue q;
-  int rid, havechoice;
+  Queue q, qi;
+  int i, j, rid, havechoice;
   Id p, d, *pp;
   Id p2, pp2;
   Solvable *s, *s2;
@@ -1790,6 +1791,8 @@ addchoicerules(Solver *solv)
     }
   solv->choicerules_ref = sat_calloc(solv->rpmrules_end, sizeof(Id));
   queue_init(&q);
+  queue_init(&qi);
+  map_init(&m, pool->nsolvables);
   for (rid = 1; rid < solv->rpmrules_end ; rid++)
     {
       r = solv->rules + rid;
@@ -1797,6 +1800,7 @@ addchoicerules(Solver *solv)
        continue;       /* only look at requires rules */
       // solver_printrule(solv, SAT_DEBUG_RESULT, r);
       queue_empty(&q);
+      queue_empty(&qi);
       havechoice = 0;
       FOR_RULELITERALS(p, pp, r)
        {
@@ -1825,11 +1829,12 @@ addchoicerules(Solver *solv)
            }
          if (p2)
            {
-             /* found one */
+             /* found installed package */
              if (!solv->allowarchchange && s->arch != s2->arch && policy_illegal_archchange(solv, s, s2))
                continue;
              if (!solv->allowvendorchange && s->vendor != s2->vendor && policy_illegal_vendorchange(solv, s, s2))
                continue;
+             queue_push(&qi, p2);
              queue_push(&q, p);
              continue;
            }
@@ -1860,6 +1865,7 @@ addchoicerules(Solver *solv)
                    continue;
                  if (!solv->allowvendorchange && s->vendor != s2->vendor && policy_illegal_vendorchange(solv, s, s2))
                    continue;
+                 queue_push(&qi, p2);
                  queue_push(&q, p);
                  continue;
                }
@@ -1869,6 +1875,40 @@ addchoicerules(Solver *solv)
        }
       if (!havechoice || !q.count)
        continue;       /* no choice */
+
+      /* now check the update rules of the installed package.
+       * if all packages of the update rules are contained in
+       * the dependency rules, there's no need to set up the choice rule */
+      map_empty(&m);
+      FOR_RULELITERALS(p, pp, r)
+        if (p > 0)
+         MAPSET(&m, p);
+      for (i = 0; i < qi.count; i++)
+       {
+         if (!qi.elements[i])
+           continue;
+         Rule *ur = solv->rules + solv->updaterules + (qi.elements[i] - pool->installed->start);
+         if (!ur->p)
+           ur = solv->rules + solv->featurerules + (qi.elements[i] - pool->installed->start);
+         if (!ur->p)
+           continue;
+         FOR_RULELITERALS(p, pp, ur)
+           if (!MAPTST(&m, p))
+             break;
+         if (p)
+           break;
+         for (j = i + 1; j < qi.count; j++)
+           if (qi.elements[i] == qi.elements[j])
+             qi.elements[j] = 0;
+       }
+      if (i == qi.count)
+       {
+#if 0
+         printf("skipping choice ");
+         solver_printrule(solv, SAT_DEBUG_RESULT, solv->rules + rid);
+#endif
+         continue;
+       }
       d = q.count ? pool_queuetowhatprovides(pool, &q) : 0;
       solver_addrule(solv, r->p, d);
       queue_push(&solv->weakruleq, solv->nrules - 1);
@@ -1881,9 +1921,15 @@ addchoicerules(Solver *solv)
 #endif
     }
   queue_free(&q);
+  queue_free(&qi);
+  map_free(&m);
   solv->choicerules_end = solv->nrules;
 }
 
+/* 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 */
 void
 disablechoicerules(Solver *solv, Rule *r)
 {
index 98f8dd0d431a556e63797a7c01770411ed6c148c..0aaa3c6eb61d29b6f68dec69c05c33ae4a3c5c8f 100644 (file)
@@ -1660,11 +1660,12 @@ solver_run_sat(Solver *solv, int disablerules, int doweak)
              return;
            }
          if (level < systemlevel || level == 1)
-           break;
+           break;              /* trouble */
+         /* something changed, so look at all rules again */
          n = 0;
-       } /* for(), decide */
+       }
 
-      if (n != solv->nrules)   /* continue if level < systemlevel */
+      if (n != solv->nrules)   /* ran into trouble, restart */
        continue;
 
       if (doweak)
@@ -2029,6 +2030,7 @@ solver_run_sat(Solver *solv, int disablerules, int doweak)
              continue;
            }
        }
+      /* no minimization found, we're finally finished! */
       break;
     }
   POOL_DEBUG(SAT_DEBUG_STATS, "solver statistics: %d learned rules, %d unsolvable, %d minimization steps\n", solv->stats_learned, solv->stats_unsolvable, minimizationsteps);
@@ -2843,6 +2845,8 @@ solver_solve(Solver *solv, Queue *job)
       extern void addchoicerules(Solver *solv);
       addchoicerules(solv);
     }
+  else
+    solv->choicerules = solv->choicerules_end = solv->nrules;
 
   /* all rules created
    * --------------------------------------------------------------