From d39445e2e8460772aacb8bd40050361d8159e8c6 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Tue, 18 Dec 2018 13:57:48 +0100 Subject: [PATCH] Refactor weak rule handling --- src/rules.c | 17 +++++++++-------- src/solver.c | 45 ++++++++++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/rules.c b/src/rules.c index df323416..e8f8ea0d 100644 --- a/src/rules.c +++ b/src/rules.c @@ -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; diff --git a/src/solver.c b/src/solver.c index b7729b4b..e020bb13 100644 --- a/src/solver.c +++ b/src/solver.c @@ -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; } -- 2.47.2