continue;
if (solv->weakrulemap.size && MAPTST(&solv->weakrulemap, i)) /* weak: silently ignore */
continue;
-
+
POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, " - disabling rule #%d\n", i);
solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, solv->rules + i);
solver_recordproblem(solv, i);
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)
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);
}
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);
}
/*
* 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;
} /* 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 */
}
disable_recommendsrules(Solver *solv, Queue *weakq)
{
Pool *pool = solv->pool;
- int i;
+ int i, rid;
for (i = 0; i < weakq->count; i++)
{
- Rule *r;
- if (!queue_contains(solv->recommendsruleq, weakq->elements[i]))
- continue;
- r = solv->rules + weakq->elements[i];
- if (r->d >= 0)
+ rid = weakq->elements[i];
+ if ((rid >= solv->recommendsrules && rid < solv->recommendsrules_end) || queue_contains(solv->recommendsruleq, rid))
{
- POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "disabling ");
- solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, r);
- solver_disablerule(solv, r);
+ Rule *r = solv->rules + rid;
+ if (r->d >= 0)
+ {
+ POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "disabling ");
+ solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, r);
+ solver_disablerule(solv, r);
+ }
}
}
}
solver_recordproblem(solv, why);
}
+/* fix a problem by disabling one or more weak rules */
+static void
+disable_weakrules(Solver *solv, Queue *weakq)
+{
+ Pool *pool = solv->pool;
+ int i;
+ Id lastweak = 0;
+ for (i = 0; i < weakq->count; i++)
+ if (weakq->elements[i] > lastweak)
+ lastweak = weakq->elements[i];
+ if (lastweak >= solv->recommendsrules && lastweak < solv->recommendsrules_end)
+ {
+ lastweak = 0;
+ for (i = 0; i < weakq->count; i++)
+ if (weakq->elements[i] < solv->recommendsrules && weakq->elements[i] > lastweak)
+ lastweak = weakq->elements[i];
+ if (lastweak < solv->pkgrules_end)
+ {
+ disable_recommendsrules(solv, weakq);
+ return;
+ }
+ }
+ if (lastweak < solv->pkgrules_end && solv->strongrecommends && solv->recommendsruleq && queue_contains(solv->recommendsruleq, lastweak))
+ {
+ disable_recommendsrules(solv, weakq);
+ return;
+ }
+ POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "disabling ");
+ solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, solv->rules + lastweak);
+ /* choice rules need special handling */
+ if (lastweak >= solv->choicerules && lastweak < solv->choicerules_end)
+ solver_disablechoicerules(solv, solv->rules + lastweak);
+ else
+ solver_fixproblem(solv, lastweak);
+}
/*-------------------------------------------------------------------
*
Map rseen;
Queue weakq;
Id pp, v, vv, why;
- int i, idx;
+ int idx;
Id *decisionmap = solv->decisionmap;
int oldproblemcount;
int oldlearntpoolcount;
if (weakq.count)
{
- Id lastweak;
/* revert problems */
solv->problems.count = oldproblemcount;
solv->learnt_pool.count = oldlearntpoolcount;
- /* find last weak */
- lastweak = 0;
- for (i = 0; i < weakq.count; i++)
- if (weakq.elements[i] > lastweak)
- lastweak = weakq.elements[i];
- if (lastweak < solv->pkgrules_end && solv->strongrecommends && solv->recommendsruleq && queue_contains(solv->recommendsruleq, lastweak))
- {
- disable_recommendsrules(solv, &weakq);
- queue_free(&weakq);
- solver_reset(solv);
- return 0;
- }
+ /* disable some weak rules */
+ disable_weakrules(solv, &weakq);
queue_free(&weakq);
- POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "disabling ");
- solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, solv->rules + lastweak);
- if (lastweak >= solv->choicerules && lastweak < solv->choicerules_end)
- solver_disablechoicerules(solv, solv->rules + lastweak);
- solver_fixproblem(solv, lastweak);
solver_reset(solv);
return 0;
}
/*-------------------------------------------------------------------
*
* branch handling
+ *
+ * format is:
+ * [ -p1 p2 p3 .. pn opt_pkg opt_data size level ]
+ *
+ * pkgs are negative if we tried them (to prevent inifinite recursion)
+ * opt_pkg: recommends: package with the recommends
+ * rule: 0
+ * opt_data: recommends: depid
+ * rule: ruleid
*/
static void
queuep_free(&solv->recommendscplxq);
queuep_free(&solv->suggestscplxq);
queuep_free(&solv->brokenorphanrules);
- queuep_free(&solv->favorq);
queuep_free(&solv->recommendsruleq);
map_free(&solv->recommendsmap);
map_free(&solv->droporphanedmap);
map_free(&solv->cleandepsmap);
map_free(&solv->allowuninstallmap);
- map_free(&solv->favormap);
- map_free(&solv->isdisfavormap);
+ solv_free(solv->favormap);
solv_free(solv->decisionmap);
solv_free(solv->rules);
solv_free(solv->watches);
solv_free(solv->obsoletes);
solv_free(solv->obsoletes_data);
solv_free(solv->specialupdaters);
- solv_free(solv->choicerules_ref);
- solv_free(solv->bestrules_pkg);
+ solv_free(solv->choicerules_info);
+ solv_free(solv->bestrules_info);
solv_free(solv->yumobsrules_info);
+ solv_free(solv->recommendsrules_info);
solv_free(solv->instbuddy);
solv_free(solv);
}
{
if (specialupdaters && (d = specialupdaters[i - installed->start]) != 0)
{
+ int j;
/* special multiversion handling, make sure best version is chosen */
if (rr->p == i && solv->decisionmap[i] >= 0)
queue_push(dq, i);
while ((p = pool->whatprovidesdata[d++]) != 0)
if (solv->decisionmap[p] >= 0)
queue_push(dq, p);
+ for (j = 0; j < dq->count; j++)
+ {
+ Id p2 = dq->elements[j];
+ if (pool->solvables[p2].repo != installed)
+ continue;
+ d = specialupdaters[i - installed->start];
+ while ((p = pool->whatprovidesdata[d++]) != 0)
+ {
+ if (solv->decisionmap[p] >= 0 || pool->solvables[p].repo == installed)
+ continue;
+ if (solvable_identical(pool->solvables + p, pool->solvables + p2))
+ queue_push(dq, p); /* identical to installed, put it on the list so we have a repo prio */
+ }
+ }
if (dq->count && solv->update_targets && solv->update_targets->elements[i - installed->start])
prune_to_update_targets(solv, solv->update_targets->elements + solv->update_targets->elements[i - installed->start], dq);
if (dq->count)
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)
{
Rule *r;
int origlevel = level;
Id p, *dp;
+ int focusbest = solv->focus_best && solv->do_extra_reordering;
+ Repo *installed = solv->installed;
/*
* decide
}
if (i == solv->nrules)
i = 1;
+ if (focusbest && i >= solv->featurerules)
+ continue;
r = solv->rules + i;
if (r->d < 0) /* ignore disabled rules */
continue;
if (r->d == 0 || solv->decisionmap[-r->p] <= 0)
continue;
}
+ if (focusbest && r->d != 0 && installed)
+ {
+ /* make sure at least one negative literal is from a new package */
+ if (!(r->p < 0 && pool->solvables[-r->p].repo != installed))
+ {
+ dp = pool->whatprovidesdata + r->d;
+ while ((p = *dp++) != 0)
+ if (p < 0 && solv->decisionmap[-p] > 0 && pool->solvables[-p].repo != installed)
+ break;
+ if (!p)
+ continue; /* sorry */
+ }
+ }
if (dq->count)
queue_empty(dq);
if (r->d == 0)
/* 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)
prune_disfavored(Solver *solv, Queue *plist)
{
int i, j;
- if (!solv->isdisfavormap.size)
- return;
- for (i = j = 0; i < plist->count; i++)
- {
+ for (i = j = 0; i < plist->count; i++)
+ {
Id p = plist->elements[i];
- if (!MAPTST(&solv->isdisfavormap, p))
- plist->elements[j++] = p;
- }
+ if (solv->favormap[p] >= 0)
+ plist->elements[j++] = p;
+ }
if (i != j)
queue_truncate(plist, j);
}
continue;
if (solv->process_orphans && solv->installed && s->repo == solv->installed && (solv->droporphanedmap_all || (solv->droporphanedmap.size && MAPTST(&solv->droporphanedmap, i - solv->installed->start))))
continue;
- if (solv->isdisfavormap.size && MAPTST(&solv->isdisfavormap, i))
+ if (solv->havedisfavored && solv->favormap[i] < 0)
continue; /* disfavored supplements, do not install */
queue_push(dqs, i);
}
}
/* filter out disfavored recommended packages */
- if (dq->count && solv->isdisfavormap.size)
+ if (dq->count && solv->havedisfavored)
prune_disfavored(solv, dq);
/* filter out all packages obsoleted by installed packages */
policy_filter_unwanted(solv, dq, POLICY_MODE_CHOOSE);
/* if we have multiple candidates we open a branch */
if (dq->count > 1)
- createbranch(solv, level, dq, s - pool->solvables, rec);
+ createbranch(solv, level, dq, s - pool->solvables, rec);
p = dq->elements[0];
POOL_DEBUG(SOLV_DEBUG_POLICY, "installing recommended %s\n", pool_solvid2str(pool, p));
olevel = level;
break;
}
*rerunp = 1;
+ return level;
}
}
return level;
if (rerun)
continue;
}
-
+
/* one final pass to make sure we decided all installed packages */
if (solv->installed)
{
lastsi = -1;
break;
}
- if (solv->isdisfavormap.size && MAPTST(&solv->isdisfavormap, p))
+ if (solv->havedisfavored && solv->favormap[p] < 0)
continue;
if (lastsi < 0 && (MAPTST(&solv->recommendsmap, p) || solver_is_supplementing(solv, pool->solvables + p)))
lastsi = i;
if (lastsi >= 0)
{
/* we have a recommended package that could not be installed */
- /* take it if our current selection is not recommended */
+ /* find current selection and take new one if it is not recommended */
for (i = starti; i < endi - 4; i++)
{
p = -solv->branches.elements[i];
if (p <= 0 || solv->decisionmap[p] != l + 1)
continue;
- if (solv->favormap.size && MAPTST(&solv->favormap, p))
- if (!(solv->isdisfavormap.size && MAPTST(&solv->isdisfavormap, p)))
- continue; /* current selection is favored */
+ if (solv->favormap && solv->favormap[p] > solv->favormap[solv->branches.elements[lastsi]])
+ continue; /* current selection is more favored */
if (!(MAPTST(&solv->recommendsmap, p) || solver_is_supplementing(solv, pool->solvables + p)))
{
lasti = lastsi;
for (; i < pool->nsolvables; i++)
if (MAPTST(addedmap, i))
queue_push(&solv->addedmap_deduceq, i);
- j = 0;
- for (i = 2; i < pool->nsolvables; i++)
- if (MAPTST(addedmap, i))
- j++;
}
static void
}
#endif
-/* sort by package id, last entry wins */
-static int
-setup_favormaps_cmp(const void *ap, const void *bp, void *dp)
-{
- const Id *a = ap, *b = bp;
- if ((*a - *b) != 0)
- return *a - *b;
- return (b[1] < 0 ? -b[1] : b[1]) - (a[1] < 0 ? -a[1] : a[1]);
-}
-
static void
-setup_favormaps(Solver *solv)
+setup_favormap(Solver *solv)
{
- Queue *q = solv->favorq;
+ Queue *job = &solv->job;
Pool *pool = solv->pool;
- int i;
- Id oldp = 0;
- if (q->count > 2)
- solv_sort(q->elements, q->count / 2, 2 * sizeof(Id), setup_favormaps_cmp, solv);
- map_grow(&solv->favormap, pool->nsolvables);
- for (i = 0; i < q->count; i += 2)
+ int i, idx;
+ Id p, pp, how, what, select;
+
+ solv_free(solv->favormap);
+ solv->favormap = solv_calloc(pool->nsolvables, sizeof(Id));
+ for (i = 0; i < job->count; i += 2)
{
- Id p = q->elements[i];
- if (p == oldp)
+ how = job->elements[i];
+ if ((how & SOLVER_JOBMASK) != SOLVER_FAVOR && (how & SOLVER_JOBMASK) != SOLVER_DISFAVOR)
continue;
- oldp = p;
- MAPSET(&solv->favormap, p);
- if (q->elements[i + 1] < 0)
+ what = job->elements[i + 1];
+ select = how & SOLVER_SELECTMASK;
+ idx = (how & SOLVER_JOBMASK) == SOLVER_FAVOR ? i + 1 : -(i + 1);
+ if (select == SOLVER_SOLVABLE_REPO)
{
- if (!solv->isdisfavormap.size)
- map_grow(&solv->isdisfavormap, pool->nsolvables);
- MAPSET(&solv->isdisfavormap, p);
+ Repo *repo = pool_id2repo(pool, what);
+ if (repo)
+ {
+ Solvable *s;
+ FOR_REPO_SOLVABLES(repo, p, s)
+ {
+ solv->favormap[p] = idx;
+ if (idx < 0)
+ solv->havedisfavored = 1;
+ }
+ }
+ }
+ FOR_JOB_SELECT(p, pp, select, what)
+ {
+ solv->favormap[p] = idx;
+ if (idx < 0)
+ solv->havedisfavored = 1;
}
}
}
int now, solve_start;
int needduprules = 0;
int hasbestinstalljob = 0;
+ int hasfavorjob = 0;
+ int haslockjob = 0;
+ int hasblacklistjob = 0;
solve_start = solv_timems(0);
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 onlynamespacerecommended=%d\n", solv->dontinstallrecommended, solv->addalreadyrecommended, solv->only_namespace_recommended);
queuep_free(&solv->update_targets);
queuep_free(&solv->cleandeps_updatepkgs);
queue_empty(&solv->ruleassertions);
- solv->bestrules_pkg = solv_free(solv->bestrules_pkg);
+ solv->bestrules_info = solv_free(solv->bestrules_info);
solv->yumobsrules_info = solv_free(solv->yumobsrules_info);
- solv->choicerules_ref = solv_free(solv->choicerules_ref);
+ solv->recommendsrules_info = solv_free(solv->recommendsrules_info);
+ solv->choicerules_info = solv_free(solv->choicerules_info);
if (solv->noupdate.size)
map_empty(&solv->noupdate);
map_zerosize(&solv->multiversion);
map_zerosize(&solv->allowuninstallmap);
map_zerosize(&solv->cleandepsmap);
map_zerosize(&solv->weakrulemap);
- map_zerosize(&solv->favormap);
- map_zerosize(&solv->isdisfavormap);
+ solv->favormap = solv_free(solv->favormap);
queue_empty(&solv->weakruleq);
solv->watches = solv_free(solv->watches);
queue_empty(&solv->ruletojob);
*/
initialnrules = solv->pkgrules_end ? solv->pkgrules_end : 1;
if (initialnrules > 1)
- deduceq2addedmap(solv, &addedmap);
+ deduceq2addedmap(solv, &addedmap); /* also enables all pkg rules */
if (solv->nrules != initialnrules)
- solver_shrinkrules(solv, initialnrules);
+ solver_shrinkrules(solv, initialnrules); /* shrink to just pkg rules */
solv->lastpkgrule = 0;
solv->pkgrules_end = 0;
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)
- solver_addjobrule(solv, installed && pool->solvables[p].repo == installed ? p : -p, 0, 0, i, weak);
+ {
+ 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
+ }
+ if (solv->nrules != oldnrules)
+ haslockjob = 1;
break;
case SOLVER_DISTUPGRADE:
POOL_DEBUG(SOLV_DEBUG_JOB, "job: distupgrade %s\n", solver_select2str(pool, select, what));
case SOLVER_FAVOR:
case SOLVER_DISFAVOR:
POOL_DEBUG(SOLV_DEBUG_JOB, "job: %s %s\n", (how & SOLVER_JOBMASK) == SOLVER_FAVOR ? "favor" : "disfavor", solver_select2str(pool, select, what));
- FOR_JOB_SELECT(p, pp, select, what)
- {
- int j;
- if (!solv->favorq)
- {
- solv->favorq = solv_calloc(1, sizeof(Queue));
- queue_init(solv->favorq);
- }
- j = solv->favorq->count + 1;
- queue_push2(solv->favorq, p, (how & SOLVER_JOBMASK) == SOLVER_FAVOR ? j : -j);
- }
+ hasfavorjob = 1;
+ break;
+ case SOLVER_BLACKLIST:
+ POOL_DEBUG(SOLV_DEBUG_JOB, "job: blacklist %s\n", solver_select2str(pool, select, what));
+ hasblacklistjob = 1;
break;
default:
POOL_DEBUG(SOLV_DEBUG_JOB, "job: unknown job\n");
assert(solv->ruletojob.count == solv->nrules - solv->jobrules);
solv->jobrules_end = solv->nrules;
- /* transform favorq into two maps */
- if (solv->favorq)
- setup_favormaps(solv);
+ /* create favormap if we have favor jobs */
+ if (hasfavorjob)
+ setup_favormap(solv);
/* now create infarch and dup rules */
if (!solv->noinfarchcheck)
#endif
if (solv->bestupdatemap_all || solv->bestupdatemap.size || hasbestinstalljob)
- solver_addbestrules(solv, hasbestinstalljob);
+ solver_addbestrules(solv, hasbestinstalljob, haslockjob);
else
solv->bestrules = solv->bestrules_end = solv->bestrules_up = solv->nrules;
else
solv->yumobsrules = solv->yumobsrules_end = solv->nrules;
+ if (hasblacklistjob)
+ solver_addblackrules(solv);
+ else
+ solv->blackrules = solv->blackrules_end = solv->nrules;
+
+ if (solv->havedisfavored && solv->strongrecommends && solv->recommendsruleq)
+ solver_addrecommendsrules(solv);
+ else
+ solv->recommendsrules = solv->recommendsrules_end = solv->nrules;
+
if (1)
solver_addchoicerules(solv);
else
solv->choicerules = solv->choicerules_end = solv->nrules;
- if (0)
- {
- for (i = solv->featurerules; i < solv->nrules; i++)
- solver_printruleclass(solv, SOLV_DEBUG_RESULT, solv->rules + i);
- }
/* all rules created
* --------------------------------------------------------------
* prepare for solving
case SOLVER_DISFAVOR:
strstart = "disfavor ";
break;
+ case SOLVER_BLACKLIST:
+ strstart = "blacklist ";
+ break;
default:
strstart = "unknown job ";
break;
char buf[64];
if (solver_ruleclass(solv, id) == SOLVER_RULE_CHOICE)
id = solver_rule2pkgrule(solv, id);
+ if (solver_ruleclass(solv, id) == SOLVER_RULE_RECOMMENDS)
+ id = solver_rule2pkgrule(solv, id);
rtype = solver_ruleinfo(solv, id, &depfrom, &depto, &dep);
if ((rtype & SOLVER_RULE_TYPEMASK) == SOLVER_RULE_JOB)
{