summaryrefslogtreecommitdiff
path: root/src/solver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/solver.c')
-rw-r--r--src/solver.c95
1 files changed, 84 insertions, 11 deletions
diff --git a/src/solver.c b/src/solver.c
index a80090d..b335e6a 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -431,7 +431,7 @@ propagate(Solver *solv, int level)
Id *decisionmap = solv->decisionmap;
Id *watches = solv->watches + pool->nsolvables; /* place ptr in middle */
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate -----\n");
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate level %d -----\n", level);
/* foreach non-propagated decision */
while (solv->propagate_index < solv->decisionq.count)
@@ -444,7 +444,7 @@ propagate(Solver *solv, int level)
IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE)
{
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "propagate for decision %d level %d\n", -pkg, level);
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "propagate decision %d:", -pkg);
solver_printruleelement(solv, SOLV_DEBUG_PROPAGATE, 0, -pkg);
}
@@ -462,10 +462,10 @@ propagate(Solver *solv, int level)
continue;
}
- IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE)
+ IF_POOLDEBUG (SOLV_DEBUG_WATCHES)
{
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE," watch triggered ");
- solver_printrule(solv, SOLV_DEBUG_PROPAGATE, r);
+ POOL_DEBUG(SOLV_DEBUG_WATCHES, " watch triggered ");
+ solver_printrule(solv, SOLV_DEBUG_WATCHES, r);
}
/*
@@ -532,12 +532,12 @@ propagate(Solver *solv, int level)
* if we found some p that is UNDEF or TRUE, move
* watch to it
*/
- IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE)
+ IF_POOLDEBUG (SOLV_DEBUG_WATCHES)
{
if (p > 0)
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, " -> move w%d to %s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, p));
+ POOL_DEBUG(SOLV_DEBUG_WATCHES, " -> move w%d to %s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, p));
else
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, " -> move w%d to !%s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, -p));
+ POOL_DEBUG(SOLV_DEBUG_WATCHES, " -> move w%d to !%s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, -p));
}
*rp = *next_rp;
@@ -593,7 +593,7 @@ propagate(Solver *solv, int level)
} /* while we have non-decided decisions */
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate end-----\n");
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate end -----\n");
return 0; /* all is well */
}
@@ -1824,6 +1824,69 @@ resolve_installed(Solver *solv, int level, int disablerules, Queue *dq)
return level;
}
+/* one or more installed cleandeps packages in dq that are to be updated */
+/* we need to emulate the code in resolve_installed */
+static void
+do_cleandeps_update_filter(Solver *solv, Queue *dq)
+{
+ Pool *pool = solv->pool;
+ Repo *installed = solv->installed;
+ Id *specialupdaters = solv->specialupdaters;
+ Id p, p2, pp, d;
+ Queue q;
+ int i, j, k;
+
+ queue_init(&q);
+ for (i = 0; i < dq->count; i++)
+ {
+ Id p = dq->elements[i];
+ if (p < 0)
+ p = -p;
+ if (pool->solvables[p].repo != installed || !MAPTST(&solv->cleandepsmap, p - installed->start))
+ continue;
+ queue_empty(&q);
+ /* find updaters */
+ if (specialupdaters && (d = specialupdaters[p - installed->start]) != 0)
+ {
+ while ((p2 = pool->whatprovidesdata[d++]) != 0)
+ if (solv->decisionmap[p2] >= 0)
+ queue_push(&q, p2);
+ }
+ else
+ {
+ Rule *r = solv->rules + solv->updaterules + (p - installed->start);
+ if (r->p)
+ {
+ FOR_RULELITERALS(p2, pp, r)
+ if (solv->decisionmap[p2] >= 0)
+ queue_push(&q, p2);
+ }
+ }
+ if (q.count && 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);
+ /* mark all elements in dq that are in the updaters list */
+ dq->elements[i] = -p;
+ for (j = 0; j < dq->count; j++)
+ {
+ p = dq->elements[j];
+ if (p < 0)
+ continue;
+ for (k = 0; k < q.count; k++)
+ if (q.elements[k] == p)
+ {
+ dq->elements[j] = -p;
+ break;
+ }
+ }
+ }
+ /* now prune to marked elements */
+ for (i = j = 0; i < dq->count; i++)
+ if ((p = dq->elements[i]) < 0)
+ dq->elements[j++] = -p;
+ dq->count = j;
+ queue_free(&q);
+}
+
static int
resolve_dependencies(Solver *solv, int level, int disablerules, Queue *dq)
{
@@ -1919,15 +1982,25 @@ resolve_dependencies(Solver *solv, int level, int disablerules, Queue *dq)
/* prune to cleandeps packages */
if (solv->cleandepsmap.size && solv->installed)
{
+ int cleandeps_update = 0;
Repo *installed = solv->installed;
for (j = 0; j < dq->count; j++)
if (pool->solvables[dq->elements[j]].repo == installed && MAPTST(&solv->cleandepsmap, dq->elements[j] - installed->start))
- break;
+ {
+ if (solv->updatemap_all || (solv->updatemap.size && MAPTST(&solv->updatemap, dq->elements[j] - installed->start)))
+ {
+ cleandeps_update = 1; /* cleandeps package is marked for update */
+ continue;
+ }
+ break;
+ }
if (j < dq->count)
{
dq->elements[0] = dq->elements[j];
queue_truncate(dq, 1);
}
+ else if (cleandeps_update)
+ do_cleandeps_update_filter(solv, dq); /* special update filter */
}
if (dq->count > 1 && postponed >= 0)
@@ -3920,7 +3993,7 @@ solver_solve(Solver *solv, Queue *job)
else
solv->yumobsrules = solv->yumobsrules_end = solv->nrules;
- if (solv->havedisfavored && solv->strongrecommends)
+ if (solv->havedisfavored && solv->strongrecommends && solv->recommendsruleq)
solver_addrecommendsrules(solv);
else
solv->recommendsrules = solv->recommendsrules_end = solv->nrules;