Id *decisionmap = solv->decisionmap;
Id *watches = solv->watches + pool->nsolvables; /* place ptr in middle */
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate level %d -----\n", level);
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "----- propagate -----\n");
/* foreach non-propagated decision */
while (solv->propagate_index < solv->decisionq.count)
IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE)
{
- POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "propagate decision %d:", -pkg);
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE, "propagate for decision %d level %d\n", -pkg, level);
solver_printruleelement(solv, SOLV_DEBUG_PROPAGATE, 0, -pkg);
}
continue;
}
- IF_POOLDEBUG (SOLV_DEBUG_WATCHES)
+ IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE)
{
- POOL_DEBUG(SOLV_DEBUG_WATCHES, " watch triggered ");
- solver_printrule(solv, SOLV_DEBUG_WATCHES, r);
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE," watch triggered ");
+ solver_printrule(solv, SOLV_DEBUG_PROPAGATE, r);
}
/*
* if we found some p that is UNDEF or TRUE, move
* watch to it
*/
- IF_POOLDEBUG (SOLV_DEBUG_WATCHES)
+ IF_POOLDEBUG (SOLV_DEBUG_PROPAGATE)
{
if (p > 0)
- POOL_DEBUG(SOLV_DEBUG_WATCHES, " -> move w%d to %s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, p));
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE, " -> move w%d to %s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, p));
else
- POOL_DEBUG(SOLV_DEBUG_WATCHES, " -> move w%d to !%s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, -p));
+ POOL_DEBUG(SOLV_DEBUG_PROPAGATE, " -> move w%d to !%s\n", (pkg == r->w1 ? 1 : 2), pool_solvid2str(pool, -p));
}
*rp = *next_rp;
} /* 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 */
}
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)
{
}
if (i == solv->nrules)
i = 1;
- if (solv->focus_best && solv->do_extra_reordering && i >= solv->featurerules)
- continue;
r = solv->rules + i;
if (r->d < 0) /* ignore disabled rules */
continue;
/* 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))
- {
- 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;
- }
+ 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)
Pool *pool = solv->pool;
Solvable *s = pool->solvables + p;
Repo *installed = solv->installed;
- Id pi, pip;
+ Id pi, pip, identicalp;
+ int startcnt, endcnt;
+
if (!solv->update_targets)
{
solv->update_targets = solv_calloc(1, sizeof(Queue));
queue_push2(solv->update_targets, p, p);
return;
}
+ identicalp = 0;
+ startcnt = solv->update_targets->count;
FOR_PROVIDES(pi, pip, s->name)
{
Solvable *si = pool->solvables + pi;
if (how & SOLVER_CLEANDEPS)
add_cleandeps_updatepkg(solv, pi);
queue_push2(solv->update_targets, pi, p);
- /* check if it's ok to keep the installed package */
+ /* remember an installed package that is identical to p */
if (s->evr == si->evr && solvable_identical(s, si))
- queue_push2(solv->update_targets, pi, pi);
+ identicalp = pi;
}
if (s->obsoletes)
{
}
}
}
+ /* also allow upgrading to an identical installed package */
+ if (identicalp)
+ {
+ for (endcnt = solv->update_targets->count; startcnt < endcnt; startcnt += 2)
+ queue_push2(solv->update_targets, solv->update_targets->elements[startcnt], identicalp);
+ }
}
static int
POOL_DEBUG(SOLV_DEBUG_STATS, "solver started\n");
POOL_DEBUG(SOLV_DEBUG_STATS, "dosplitprovides=%d, noupdateprovide=%d, noinfarchcheck=%d\n", solv->dosplitprovides, solv->noupdateprovide, solv->noinfarchcheck);
POOL_DEBUG(SOLV_DEBUG_STATS, "allowuninstall=%d, allowdowngrade=%d, allownamechange=%d, allowarchchange=%d, allowvendorchange=%d\n", solv->allowuninstall, solv->allowdowngrade, solv->allownamechange, solv->allowarchchange, solv->allowvendorchange);
- POOL_DEBUG(SOLV_DEBUG_STATS, "dupallowdowngrade=%d, dupallownamechange=%d, dupallowarchchange=%d, dupallowvendorchange=%d\n", solv->dup_allowdowngrade, solv->dup_allownamechange, solv->dup_allowarchchange, solv->dup_allowvendorchange);
POOL_DEBUG(SOLV_DEBUG_STATS, "promoteepoch=%d, forbidselfconflicts=%d\n", pool->promoteepoch, pool->forbidselfconflicts);
POOL_DEBUG(SOLV_DEBUG_STATS, "obsoleteusesprovides=%d, implicitobsoleteusesprovides=%d, obsoleteusescolors=%d, implicitobsoleteusescolors=%d\n", pool->obsoleteusesprovides, pool->implicitobsoleteusesprovides, pool->obsoleteusescolors, pool->implicitobsoleteusescolors);
POOL_DEBUG(SOLV_DEBUG_STATS, "dontinstallrecommended=%d, addalreadyrecommended=%d\n", solv->dontinstallrecommended, solv->addalreadyrecommended);
name_s = s;
}
solver_addjobrule(solv, -p, 0, 0, i, weak);
-#ifdef ENABLE_LINKED_PKGS
- if (solv->instbuddy && installed && s->repo == installed && solv->instbuddy[p - installed->start] > 1)
- solver_addjobrule(solv, -solv->instbuddy[p - installed->start], 0, 0, i, weak);
-#endif
}
/* special case for "erase a specific solvable": we also
* erase all other solvables with that name, so that they
}
}
FOR_JOB_SELECT(p, pp, select, what)
- {
- s = pool->solvables + p;
- solver_addjobrule(solv, installed && s->repo == installed ? p : -p, 0, 0, i, weak);
-#ifdef ENABLE_LINKED_PKGS
- if (solv->instbuddy && installed && s->repo == installed && solv->instbuddy[p - installed->start] > 1)
- solver_addjobrule(solv, solv->instbuddy[p - installed->start], 0, 0, i, weak);
-#endif
- }
+ solver_addjobrule(solv, installed && pool->solvables[p].repo == installed ? p : -p, 0, 0, i, weak);
break;
case SOLVER_DISTUPGRADE:
POOL_DEBUG(SOLV_DEBUG_JOB, "job: distupgrade %s\n", solver_select2str(pool, select, what));