From 38153ed6cf8573744574b9eb4afb98b9095da4e4 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Mon, 27 Jul 2009 11:51:00 +0200 Subject: [PATCH] - do not set up unneeded choice rules --- examples/solv.c | 1 + src/rules.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- src/solver.c | 10 +++++++--- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/examples/solv.c b/examples/solv.c index 52a965e..c53dca9 100644 --- a/examples/solv.c +++ b/examples/solv.c @@ -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); } diff --git a/src/rules.c b/src/rules.c index 0069e75..225c4d8 100644 --- a/src/rules.c +++ b/src/rules.c @@ -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) { diff --git a/src/solver.c b/src/solver.c index 98f8dd0..0aaa3c6 100644 --- a/src/solver.c +++ b/src/solver.c @@ -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 * -------------------------------------------------------------- -- 2.7.4