diff options
Diffstat (limited to 'src/solver.c')
-rw-r--r-- | src/solver.c | 95 |
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; |