From 894382f0c4ddf6d34b264544c3523a9094ec2a09 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Tue, 6 Oct 2020 13:29:12 +0200 Subject: [PATCH] Only do extra choicerule checking for newest packages For old versions we prefer the choicerule so that we do not switch to different providers instead of updating the package. --- src/rules.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/src/rules.c b/src/rules.c index 12d80b50..6c8e82ba 100644 --- a/src/rules.c +++ b/src/rules.c @@ -3187,6 +3187,44 @@ solver_choicerulecheck(Solver *solv, Id pi, Rule *r, Map *m, Queue *q) return 1; /* none of the new packages provided it */ } +static int +solver_choicerulecheck2(Solver *solv, Id pi, Id pt, Queue *q) +{ + Pool *pool = solv->pool; + Rule *ur; + Id p, pp; + int i; + + if (!q->count || q->elements[0] != pi) + { + if (q->count) + queue_empty(q); + ur = solv->rules + solv->updaterules + (pi - pool->installed->start); + if (!ur->p) + ur = solv->rules + solv->featurerules + (pi - pool->installed->start); + if (!ur->p) + return 0; + queue_push2(q, pi, 0); + FOR_RULELITERALS(p, pp, ur) + if (p > 0 && p != pi) + queue_push(q, p); + queue_push(q, pi); + } + if (q->count <= 3) + return q->count == 3 && q->elements[2] == pt ? 1 : 0; + if (!q->elements[1]) + { + queue_deleten(q, 0, 2); + policy_filter_unwanted(solv, q, POLICY_MODE_CHOOSE); + queue_unshift(q, 1); /* filter mark */ + queue_unshift(q, pi); + } + for (i = 2; i < q->count; i++) + if (q->elements[i] == pt) + return 1; + return 0; /* not newest */ +} + static inline void queue_removeelement(Queue *q, Id el) { @@ -3251,13 +3289,14 @@ solver_addchoicerules(Solver *solv) Pool *pool = solv->pool; Map m, mneg; Rule *r; - Queue q, qi, qcheck, infoq; + Queue q, qi, qcheck, qcheck2, infoq; int i, j, rid, havechoice, negcnt; Id p, d, pp, p2; Solvable *s; Id lastaddedp, lastaddedd; int lastaddedcnt; unsigned int now; + int isnewest = 0; solv->choicerules = solv->nrules; if (!pool->installed) @@ -3270,6 +3309,7 @@ solver_addchoicerules(Solver *solv) queue_init(&q); queue_init(&qi); queue_init(&qcheck); + queue_init(&qcheck2); queue_init(&infoq); map_init(&m, pool->nsolvables); map_init(&mneg, pool->nsolvables); @@ -3301,6 +3341,7 @@ solver_addchoicerules(Solver *solv) continue; if (s->repo == pool->installed) { + queue_push2(&qi, p, p); queue_push(&q, p); continue; } @@ -3319,6 +3360,9 @@ solver_addchoicerules(Solver *solv) /* package p is independent of the installed ones */ havechoice = 1; } +#if 0 + printf("havechoice: %d qcount %d qicount %d\n", havechoice, q.count, qi.count); +#endif if (!havechoice || !q.count || !qi.count) continue; /* no choice */ @@ -3326,13 +3370,25 @@ solver_addchoicerules(Solver *solv) if (p > 0) MAPSET(&m, p); + isnewest = 1; + FOR_RULELITERALS(p, pp, r) + { + if (p > 0) + break; + p2 = choicerule_find_installed(pool, -p); + if (p2 && !solver_choicerulecheck2(solv, p2, -p, &qcheck2)) + { + isnewest = 0; + break; + } + } /* do extra checking */ for (i = j = 0; i < qi.count; i += 2) { p2 = qi.elements[i]; if (!p2) continue; - if (solver_choicerulecheck(solv, p2, r, &m, &qcheck)) + if (isnewest && solver_choicerulecheck(solv, p2, r, &m, &qcheck)) { /* oops, remove element p from q */ queue_removeelement(&q, qi.elements[i + 1]); @@ -3426,6 +3482,7 @@ solver_addchoicerules(Solver *solv) queue_free(&q); queue_free(&qi); queue_free(&qcheck); + queue_free(&qcheck2); queue_free(&infoq); map_free(&m); map_free(&mneg); -- 2.47.2