summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/problems.c15
-rw-r--r--src/rules.c42
-rw-r--r--src/solver.c8
3 files changed, 56 insertions, 9 deletions
diff --git a/src/problems.c b/src/problems.c
index 5cf42a3..afb6639 100644
--- a/src/problems.c
+++ b/src/problems.c
@@ -441,9 +441,6 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
return; /* false alarm */
p = solv->installed->start + (why - solv->updaterules);
- rr = solv->rules + solv->featurerules + (why - solv->updaterules);
- if (!rr->p)
- rr = solv->rules + why;
if (solv->dupmap_all && solv->rules[why].p != p && solv->decisionmap[p] > 0)
{
/* distupgrade case, allow to keep old package */
@@ -453,6 +450,9 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
}
if (solv->decisionmap[p] > 0)
return; /* false alarm, turned out we can keep the package */
+ rr = solv->rules + solv->featurerules + (why - solv->updaterules);
+ if (!rr->p)
+ rr = solv->rules + why;
if (rr->w2)
{
int mvrp = 0; /* multi-version replacement */
@@ -496,12 +496,19 @@ convertsolution(Solver *solv, Id why, Queue *solutionq)
queue_push(solutionq, solv->ruletojob.elements[-p - solv->jobrules] + 1);
return;
}
+ if (solv->decisionmap[p] > 0)
+ {
+ /* disable best rule by keeping the old package */
+ queue_push(solutionq, SOLVER_SOLUTION_BEST);
+ queue_push(solutionq, p);
+ return;
+ }
rr = solv->rules + solv->featurerules + (p - solv->installed->start);
if (!rr->p)
rr = solv->rules + solv->updaterules + (p - solv->installed->start);
mvrp = 0; /* multi-version replacement */
FOR_RULELITERALS(rp, dp, rr)
- if (rp > 0 && solv->decisionmap[rp] > 0)
+ if (rp > 0 && solv->decisionmap[rp] > 0 && pool->solvables[rp].repo != solv->installed)
{
mvrp = rp;
if (!(solv->noobsoletes.size && MAPTST(&solv->noobsoletes, rp)))
diff --git a/src/rules.c b/src/rules.c
index 277f771..4b50c57 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -1385,6 +1385,8 @@ solver_addduprules(Solver *solv, Map *addedmap)
}
if (!ip)
solver_addrule(solv, -p, 0); /* no match, sorry */
+ else
+ MAPSET(&solv->dupmap, p); /* for best rules processing */
}
}
else if (!MAPTST(&solv->dupmap, p))
@@ -2432,6 +2434,37 @@ solver_disablechoicerules(Solver *solv, Rule *r)
}
}
+static void
+prune_to_update_targets(Solver *solv, Id *cp, Queue *q)
+{
+ int i, j;
+ Id p, *cp2;
+ for (i = j = 0; i < q->count; i++)
+ {
+ p = q->elements[i];
+ for (cp2 = cp; *cp2; cp2++)
+ if (*cp2 == p)
+ {
+ q->elements[j++] = p;
+ break;
+ }
+ }
+ queue_truncate(q, j);
+}
+
+static void
+prune_to_dup_packages(Solver *solv, Id p, Queue *q)
+{
+ int i, j;
+ for (i = j = 0; i < q->count; i++)
+ {
+ Id p = q->elements[i];
+ if (MAPTST(&solv->dupmap, p))
+ q->elements[j++] = p;
+ }
+ queue_truncate(q, j);
+}
+
void
solver_addbestrules(Solver *solv, int havebestinstalljobs)
{
@@ -2518,8 +2551,11 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs)
if (p2 > 0)
queue_push(&q, p2);
}
+ if (solv->update_targets && solv->update_targets->elements[p - installed->start])
+ prune_to_update_targets(solv, solv->update_targets->elements + solv->update_targets->elements[p - installed->start], &q);
+ if (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))
+ prune_to_dup_packages(solv, p, &q);
/* select best packages, just look at prio and version */
- oldcnt = q.count;
policy_filter_unwanted(solv, &q, POLICY_MODE_RECOMMEND);
if (!q.count)
continue; /* orphaned */
@@ -2534,6 +2570,10 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs)
FOR_RULELITERALS(p2, pp2, r)
if (p2 > 0)
queue_push(&q2, p2);
+ if (solv->update_targets && solv->update_targets->elements[p - installed->start])
+ prune_to_update_targets(solv, solv->update_targets->elements + solv->update_targets->elements[p - installed->start], &q2);
+ if (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))
+ prune_to_dup_packages(solv, p, &q);
policy_filter_unwanted(solv, &q2, POLICY_MODE_RECOMMEND);
for (j = 0; j < q2.count; j++)
queue_pushunique(&q, q2.elements[j]);
diff --git a/src/solver.c b/src/solver.c
index 6e2acba..9880442 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -3237,10 +3237,7 @@ solver_solve(Solver *solv, Queue *job)
solv->infarchrules = solv->infarchrules_end = solv->nrules;
if (hasdupjob)
- {
- solver_addduprules(solv, &addedmap);
- solver_freedupmaps(solv); /* no longer needed */
- }
+ solver_addduprules(solv, &addedmap);
else
solv->duprules = solv->duprules_end = solv->nrules;
@@ -3249,6 +3246,9 @@ solver_solve(Solver *solv, Queue *job)
else
solv->bestrules = solv->bestrules_end = solv->nrules;
+ if (hasdupjob)
+ solver_freedupmaps(solv); /* no longer needed */
+
if (1)
solver_addchoicerules(solv);
else