solv->decisionq_why.count--;
solv->propagate_index = solv->decisionq.count;
}
- while (solv->branches.count && solv->branches.elements[solv->branches.count - 1] <= -level)
+ while (solv->branches.count && solv->branches.elements[solv->branches.count - 1] >= level)
{
solv->branches.count--;
while (solv->branches.count && solv->branches.elements[solv->branches.count - 1] >= 0)
solv->branches.count--;
+ while (solv->branches.count && solv->branches.elements[solv->branches.count - 1] < 0)
+ solv->branches.count--;
}
if (solv->recommends_index > solv->decisionq.count)
solv->recommends_index = -1; /* rebuild recommends/suggests maps */
if (dq->count > 1)
{
/* multiple candidates, open a branch */
+ queue_push(&solv->branches, -dq->elements[0]);
for (i = 1; i < dq->count; i++)
queue_push(&solv->branches, dq->elements[i]);
- queue_push(&solv->branches, -level);
+ queue_push(&solv->branches, level);
}
p = dq->elements[0];
solv_free(solv->specialupdaters);
solv_free(solv->choicerules_ref);
solv_free(solv->bestrules_pkg);
+ solv_free(solv->yumobsrules_info);
solv_free(solv->instbuddy);
solv_free(solv);
}
return solv->break_orphans;
case SOLVER_FLAG_FOCUS_INSTALLED:
return solv->focus_installed;
+ case SOLVER_FLAG_YUM_OBSOLETES:
+ return solv->do_yum_obsoletes;
default:
break;
}
case SOLVER_FLAG_FOCUS_INSTALLED:
solv->focus_installed = value;
break;
+ case SOLVER_FLAG_YUM_OBSOLETES:
+ solv->do_yum_obsoletes = value;
+ break;
default:
break;
}
if (dq.count > 1)
{
/* multiple candidates, open a branch */
+ queue_push(&solv->branches, -dq.elements[0]);
for (i = 1; i < dq.count; i++)
queue_push(&solv->branches, dq.elements[i]);
- queue_push(&solv->branches, -level);
+ queue_push(&solv->branches, level);
}
p = dq.elements[0];
POOL_DEBUG(SOLV_DEBUG_POLICY, "installing recommended %s\n", pool_solvid2str(pool, p));
solv->solution_callback(solv, solv->solution_callback_data);
if (solv->branches.count)
{
- int i = solv->branches.count - 1;
- int l = -solv->branches.elements[i];
+ int l, endi = 0;
Id why;
-
- for (; i > 0; i--)
- if (solv->branches.elements[i - 1] < 0)
- break;
- p = solv->branches.elements[i];
- POOL_DEBUG(SOLV_DEBUG_SOLVER, "branching with %s\n", pool_solvid2str(pool, p));
- queue_empty(&dq);
- for (j = i + 1; j < solv->branches.count; j++)
- queue_push(&dq, solv->branches.elements[j]);
- solv->branches.count = i;
- level = l;
- revert(solv, level);
- if (dq.count > 1)
- for (j = 0; j < dq.count; j++)
- queue_push(&solv->branches, dq.elements[j]);
- olevel = level;
- why = -solv->decisionq_why.elements[solv->decisionq_why.count];
- assert(why >= 0);
- level = setpropagatelearn(solv, level, p, disablerules, why);
- if (level == 0)
- break;
- continue;
+ p = l = 0;
+ for (i = solv->branches.count - 1; i >= 0; i--)
+ {
+ p = solv->branches.elements[i];
+ if (p > 0 && !l)
+ {
+ endi = i + 1;
+ l = p;
+ }
+ else if (p > 0)
+ break;
+ else if (p < 0)
+ l = 0;
+ }
+ if (i >= 0)
+ {
+ while (i > 0 && solv->branches.elements[i - 1] > 0)
+ i--;
+ p = solv->branches.elements[i];
+ solv->branches.elements[i] = -p;
+ while (i > 0 && solv->branches.elements[i - 1] < 0)
+ i--;
+ POOL_DEBUG(SOLV_DEBUG_SOLVER, "branching with %s\n", pool_solvid2str(pool, p));
+ queue_empty(&dq);
+ queue_insertn(&dq, 0, endi - i, solv->branches.elements + i);
+ level = l;
+ revert(solv, level);
+ queue_insertn(&solv->branches, solv->branches.count, dq.count, dq.elements);
+ /* hack: revert simply sets the count, so we can still access the reverted elements */
+ why = -solv->decisionq_why.elements[solv->decisionq_why.count];
+ assert(why >= 0);
+ olevel = level;
+ level = setpropagatelearn(solv, level, p, disablerules, why);
+ if (level == 0)
+ break;
+ continue;
+ }
}
/* all branches done, we're finally finished */
break;
/* auto-minimization step */
if (solv->branches.count)
{
- int l = 0, lasti = -1, lastl = -1;
+ int l = 0, lasti = -1, lastsi = -1, endi = 0;
Id why;
-
- p = 0;
+ p = l = 0;
+ if (solv->recommends_index < solv->decisionq.count)
+ policy_update_recommendsmap(solv);
for (i = solv->branches.count - 1; i >= 0; i--)
{
p = solv->branches.elements[i];
- if (p < 0)
- l = -p;
- else if (p > 0 && solv->decisionmap[p] > l + 1)
+ if (p > 0 && !l)
{
- lasti = i;
- lastl = l;
+ l = p;
+ endi = i + 1;
+ lastsi = -1;
+ }
+ else if (p > 0)
+ {
+ if (solv->decisionmap[p] > l + 1)
+ lasti = i;
+ else
+ {
+ if (MAPTST(&solv->recommendsmap, p) || solver_is_supplementing(solv, pool->solvables + p))
+ {
+ lastsi = p;
+ }
+ }
+ }
+ else if (p < 0)
+ {
+ l = 0;
+ if (lastsi >= 0)
+ {
+ p = -p;
+ if (solv->decisionmap[p] == l)
+ {
+ if (!(MAPTST(&solv->recommendsmap, p) || solver_is_supplementing(solv, pool->solvables + p)))
+ lasti = lastsi;
+ }
+ }
}
}
if (lasti >= 0)
{
- /* kill old solvable so that we do not loop */
+ int starti;
+ /* find start of branch */
+ for (i = lasti; i && solv->branches.elements[i] >= 0; )
+ i--;
+ while (i > 0 && solv->branches.elements[i] < 0)
+ i--;
+ starti = i ? i + 1 : 0;
+#if 0
+ printf("minimization group level %d [%d-%d]:\n", solv->branches.elements[endi - 1], starti, endi);
+ for (i = starti; i < endi - 1; i++)
+ printf("%c %c%s\n", i == lasti ? 'x' : ' ', solv->branches.elements[i] >= 0 ? ' ' : '-', pool_solvid2str(pool, solv->branches.elements[i] >= 0 ? solv->branches.elements[i] : -solv->branches.elements[i]));
+#endif
+ l = solv->branches.elements[endi - 1];
p = solv->branches.elements[lasti];
- solv->branches.elements[lasti] = 0;
- POOL_DEBUG(SOLV_DEBUG_SOLVER, "minimizing %d -> %d with %s\n", solv->decisionmap[p], lastl, pool_solvid2str(pool, p));
+ solv->branches.elements[lasti] = -p;
+ POOL_DEBUG(SOLV_DEBUG_SOLVER, "minimizing %d -> %d with %s\n", solv->decisionmap[p], l, pool_solvid2str(pool, p));
minimizationsteps++;
-
- level = lastl;
+ queue_empty(&dq);
+ for (i = starti; i < endi - 1; i++)
+ if (solv->branches.elements[i] < 0)
+ queue_push(&dq, solv->branches.elements[i]);
+ for (i = starti; i < endi; i++)
+ if (solv->branches.elements[i] > 0)
+ queue_push(&dq, solv->branches.elements[i]);
+ if (dq.elements[dq.count - 2] <= 0)
+ queue_empty(&dq);
+ level = l;
revert(solv, level);
+ queue_insertn(&solv->branches, solv->branches.count, dq.count, dq.elements);
+ /* hack: revert simply sets the count, so we can still access the reverted elements */
why = -solv->decisionq_why.elements[solv->decisionq_why.count];
assert(why >= 0);
olevel = level;
queuep_free(&solv->cleandeps_updatepkgs);
queue_empty(&solv->ruleassertions);
solv->bestrules_pkg = solv_free(solv->bestrules_pkg);
+ solv->yumobsrules_info = solv_free(solv->yumobsrules_info);
solv->choicerules_ref = solv_free(solv->choicerules_ref);
if (solv->noupdate.size)
map_empty(&solv->noupdate);
if (hasdupjob)
solver_freedupmaps(solv); /* no longer needed */
+ if (solv->do_yum_obsoletes)
+ solver_addyumobsrules(solv);
+ else
+ solv->yumobsrules = solv->yumobsrules_end = solv->nrules;
+
if (1)
solver_addchoicerules(solv);
else
if (why > 0)
return SOLVER_REASON_RESOLVE;
/* weak or orphaned */
- if (solv->decisionq.count < solv->decisioncnt_orphan)
+ if (i < solv->decisioncnt_orphan)
return SOLVER_REASON_WEAKDEP;
return SOLVER_REASON_RESOLVE_ORPHAN;
}
if (!p2 && found)
{
queue_push(whyq, SOLVER_REASON_RECOMMENDED);
- queue_push2(whyq, p2, rec);
+ queue_push2(whyq, i, rec);
}
}
}