From 1fda7cd65aced7607140a8ab0b03f76e1f56e9fa Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Thu, 2 Nov 2017 12:51:49 +0100 Subject: [PATCH] Also disable the corresponding forcebest rule when disabling a job --- src/problems.c | 29 ++++++++++-- src/rules.c | 61 +++++++++++++++---------- src/solver.c | 29 ++++++------ src/solver.h | 1 + test/testcases/forcebest/forcebest_in.t | 8 +--- 5 files changed, 77 insertions(+), 51 deletions(-) diff --git a/src/problems.c b/src/problems.c index 2ffb6f9d..2b5ef53a 100644 --- a/src/problems.c +++ b/src/problems.c @@ -35,7 +35,6 @@ void solver_disableproblem(Solver *solv, Id v) { - Rule *r; int i; Id *jp; @@ -76,9 +75,19 @@ solver_disableproblem(Solver *solv, Id v) } v = -(v + 1); jp = solv->ruletojob.elements; - for (i = solv->jobrules, r = solv->rules + i; i < solv->jobrules_end; i++, r++, jp++) + if (solv->bestrules_pkg) + { + int ni = solv->bestrules_end - solv->bestrules; + for (i = 0; i < ni; i++) + { + int j = solv->bestrules_pkg[i]; + if (j < 0 && jp[-j - solv->jobrules] == v) + solver_disablerule(solv, solv->rules + solv->bestrules + i); + } + } + for (i = solv->jobrules; i < solv->jobrules_end; i++, jp++) if (*jp == v) - solver_disablerule(solv, r); + solver_disablerule(solv, solv->rules + i); } /*------------------------------------------------------------------- @@ -133,9 +142,19 @@ solver_enableproblem(Solver *solv, Id v) } v = -(v + 1); jp = solv->ruletojob.elements; - for (i = solv->jobrules, r = solv->rules + i; i < solv->jobrules_end; i++, r++, jp++) + if (solv->bestrules_pkg) + { + int ni = solv->bestrules_end - solv->bestrules; + for (i = 0; i < ni; i++) + { + int j = solv->bestrules_pkg[i]; + if (j < 0 && jp[-j - solv->jobrules] == v) + solver_enablerule(solv, solv->rules + solv->bestrules + i); + } + } + for (i = solv->jobrules; i < solv->jobrules_end; i++, jp++) if (*jp == v) - solver_enablerule(solv, r); + solver_enablerule(solv, solv->rules + i); } diff --git a/src/rules.c b/src/rules.c index 2e3444b4..261e8595 100644 --- a/src/rules.c +++ b/src/rules.c @@ -1466,7 +1466,7 @@ disableupdaterule(Solver *solv, Id p) { int i, ni; ni = solv->bestrules_end - solv->bestrules; - for (i = 0; i < ni; i++) + for (i = solv->bestrules_up - solv->bestrules; i < ni; i++) if (solv->bestrules_pkg[i] == p) solver_disablerule(solv, solv->rules + solv->bestrules + i); } @@ -1509,7 +1509,7 @@ reenableupdaterule(Solver *solv, Id p) { int i, ni; ni = solv->bestrules_end - solv->bestrules; - for (i = 0; i < ni; i++) + for (i = solv->bestrules_up - solv->bestrules; i < ni; i++) if (solv->bestrules_pkg[i] == p) solver_enablerule(solv, solv->rules + solv->bestrules + i); } @@ -3257,36 +3257,47 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs) { for (i = 0; i < solv->job.count; i += 2) { - if ((solv->job.elements[i] & (SOLVER_JOBMASK | SOLVER_FORCEBEST)) == (SOLVER_INSTALL | SOLVER_FORCEBEST)) + Id how = solv->job.elements[i]; + if ((how & (SOLVER_JOBMASK | SOLVER_FORCEBEST)) == (SOLVER_INSTALL | SOLVER_FORCEBEST)) { int j; Id p2, pp2; for (j = 0; j < solv->ruletojob.count; j++) - if (solv->ruletojob.elements[j] == i) - break; - if (j == solv->ruletojob.count) - continue; - r = solv->rules + solv->jobrules + j; - queue_empty(&q); - FOR_RULELITERALS(p2, pp2, r) - if (p2 > 0) - queue_push(&q, p2); - if (!q.count) - continue; /* orphaned */ - /* select best packages, just look at prio and version */ - oldcnt = q.count; - policy_filter_unwanted(solv, &q, POLICY_MODE_RECOMMEND); - if (q.count == oldcnt) - continue; /* nothing filtered */ - p2 = queue_shift(&q); - if (q.count < 2) - solver_addrule(solv, p2, q.count ? q.elements[0] : 0, 0); - else - solver_addrule(solv, p2, 0, pool_queuetowhatprovides(pool, &q)); - queue_push(&r2pkg, -(solv->jobrules + j)); + { + if (solv->ruletojob.elements[j] != i) + continue; + r = solv->rules + solv->jobrules + j; + queue_empty(&q); + queue_empty(&q2); + FOR_RULELITERALS(p2, pp2, r) + { + if (p2 > 0) + queue_push(&q, p2); + else if (p2 < 0) + queue_push(&q2, p2); + } + if (!q.count) + continue; /* orphaned */ + /* select best packages, just look at prio and version */ + oldcnt = q.count; + policy_filter_unwanted(solv, &q, POLICY_MODE_RECOMMEND); + if (q.count == oldcnt) + continue; /* nothing filtered */ + if (q2.count) + queue_insertn(&q, 0, q2.count, q2.elements); + p2 = queue_shift(&q); + if (q.count < 2) + solver_addrule(solv, p2, q.count ? q.elements[0] : 0, 0); + else + solver_addrule(solv, p2, 0, pool_queuetowhatprovides(pool, &q)); + if ((how & SOLVER_WEAK) != 0) + queue_push(&solv->weakruleq, solv->nrules - 1); + queue_push(&r2pkg, -(solv->jobrules + j)); + } } } } + solv->bestrules_up = solv->nrules; if (installed && (solv->bestupdatemap_all || solv->bestupdatemap.size)) { diff --git a/src/solver.c b/src/solver.c index b9d91d28..1339a5bb 100644 --- a/src/solver.c +++ b/src/solver.c @@ -288,6 +288,8 @@ makeruledecisions(Solver *solv) POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "conflict with system solvable, disabling rule #%d\n", ri); if (ri >= solv->jobrules && ri < solv->jobrules_end) v = -(solv->ruletojob.elements[ri - solv->jobrules] + 1); + else if (ri >= solv->bestrules && ri < solv->bestrules_up && solv->bestrules_pkg[ri - solv->bestrules] < 0) + v = -(solv->ruletojob.elements[-solv->bestrules_pkg[ri - solv->bestrules] - solv->jobrules] + 1); else v = ri; queue_push(&solv->problems, v); @@ -329,6 +331,8 @@ makeruledecisions(Solver *solv) POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "conflict with pkg rule, disabling rule #%d\n", ri); if (ri >= solv->jobrules && ri < solv->jobrules_end) v = -(solv->ruletojob.elements[ri - solv->jobrules] + 1); + else if (ri >= solv->bestrules && ri < solv->bestrules_up && solv->bestrules_pkg[ri - solv->bestrules] < 0) + v = -(solv->ruletojob.elements[-solv->bestrules_pkg[ri - solv->bestrules] - solv->jobrules] + 1); else v = ri; queue_push(&solv->problems, v); @@ -383,9 +387,12 @@ makeruledecisions(Solver *solv) POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, " - disabling rule #%d\n", i); solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, solv->rules + i); - v = i; if (i >= solv->jobrules && i < solv->jobrules_end) v = -(solv->ruletojob.elements[i - solv->jobrules] + 1); + else if (i >= solv->bestrules && i < solv->bestrules_up && solv->bestrules_pkg[i - solv->bestrules] < 0) + v = -(solv->ruletojob.elements[-solv->bestrules_pkg[i - solv->bestrules] - solv->jobrules] + 1); + else + v = i; queue_push(&solv->problems, v); } queue_push(&solv->problems, 0); @@ -448,6 +455,8 @@ makeruledecisions(Solver *solv) if (ri >= solv->jobrules && ri < solv->jobrules_end) v = -(solv->ruletojob.elements[ri - solv->jobrules] + 1); + else if (ri >= solv->bestrules && ri < solv->bestrules_up && solv->bestrules_pkg[ri - solv->bestrules] < 0) + v = -(solv->ruletojob.elements[-solv->bestrules_pkg[ri - solv->bestrules] - solv->jobrules] + 1); else v = ri; solver_disableproblem(solv, v); @@ -1019,6 +1028,8 @@ analyze_unsolvable_rule(Solver *solv, Rule *r, Queue *weakq, Map *rseen) /* turn rule into problem */ if (why >= solv->jobrules && why < solv->jobrules_end) why = -(solv->ruletojob.elements[why - solv->jobrules] + 1); + else if (why >= solv->bestrules && why < solv->bestrules_up && solv->bestrules_pkg[why - solv->bestrules] < 0) + why = -(solv->ruletojob.elements[-solv->bestrules_pkg[why - solv->bestrules] - solv->jobrules] + 1); /* normalize dup/infarch rules */ if (why > solv->infarchrules && why < solv->infarchrules_end) { @@ -3494,7 +3505,6 @@ solver_solve(Solver *solv, Queue *job) deduceq2addedmap(solv, &addedmap); if (solv->nrules != initialnrules) solver_shrinkrules(solv, initialnrules); - solv->nrules = initialnrules; solv->lastpkgrule = 0; solv->pkgrules_end = 0; @@ -4021,18 +4031,7 @@ solver_solve(Solver *solv, Queue *job) /* now create infarch and dup rules */ if (!solv->noinfarchcheck) - { - solver_addinfarchrules(solv, &addedmap); -#if 0 - if (pool->implicitobsoleteusescolors) - { - /* currently doesn't work well with infarch rules, so make - * them weak */ - for (i = solv->infarchrules; i < solv->infarchrules_end; i++) - queue_push(&solv->weakruleq, i); - } -#endif - } + solver_addinfarchrules(solv, &addedmap); else solv->infarchrules = solv->infarchrules_end = solv->nrules; @@ -4049,7 +4048,7 @@ solver_solve(Solver *solv, Queue *job) if (solv->bestupdatemap_all || solv->bestupdatemap.size || hasbestinstalljob) solver_addbestrules(solv, hasbestinstalljob); else - solv->bestrules = solv->bestrules_end = solv->nrules; + solv->bestrules = solv->bestrules_end = solv->bestrules_up = solv->nrules; if (needduprules) solver_freedupmaps(solv); /* no longer needed */ diff --git a/src/solver.h b/src/solver.h index 1b85fb34..ebb2232b 100644 --- a/src/solver.h +++ b/src/solver.h @@ -68,6 +68,7 @@ struct _Solver { Id duprules_end; Id bestrules; /* rules from SOLVER_FORCEBEST */ + Id bestrules_up; /* update rule part starts here*/ Id bestrules_end; Id *bestrules_pkg; diff --git a/test/testcases/forcebest/forcebest_in.t b/test/testcases/forcebest/forcebest_in.t index aaf2aa1d..93165c8b 100644 --- a/test/testcases/forcebest/forcebest_in.t +++ b/test/testcases/forcebest/forcebest_in.t @@ -11,19 +11,15 @@ system i686 rpm system job install name A [forcebest] result transaction,problems -#>erase D-1-1.noarch@system -#>install A-3-1.noarch@available #>problem 1210fdfb info package D-1-1.noarch conflicts with A = 3-1 provided by A-3-1.noarch #>problem 1210fdfb solution 0d75a914 erase D-1-1.noarch@system -#>problem 1210fdfb solution d85f7c4e deljob install name A [forcebest] +#>problem 1210fdfb solution ee74e60f deljob install name A [forcebest] # currently bestobeypolicy is a noop for install jobs nextjob solverflags bestobeypolicy job install name A [forcebest] result transaction,problems -#>erase D-1-1.noarch@system -#>install A-3-1.noarch@available #>problem 1210fdfb info package D-1-1.noarch conflicts with A = 3-1 provided by A-3-1.noarch #>problem 1210fdfb solution 0d75a914 erase D-1-1.noarch@system -#>problem 1210fdfb solution d85f7c4e deljob install name A [forcebest] +#>problem 1210fdfb solution ee74e60f deljob install name A [forcebest] -- 2.47.2