Id p, *dp, rp = 0;
Rule *rr;
- assert(why >= solv->updaterules && why < solv->updaterules_end);
/* check if this is a false positive, i.e. the update rule is fulfilled */
rr = solv->rules + why;
FOR_RULELITERALS(p, dp, rr)
if (p > 0 && solv->decisionmap[p] > 0)
- break;
- if (p)
- return; /* false alarm */
+ return; /* false alarm */
p = solv->installed->start + (why - solv->updaterules);
rr = solv->rules + solv->featurerules + (why - solv->updaterules);
queue_push(solutionq, rp);
return;
}
+ if (why >= solv->bestrules && why < solv->bestrules_end)
+ {
+ int mvrp;
+ Id p, *dp, rp = 0;
+ Rule *rr;
+ /* check false positive */
+ rr = solv->rules + why;
+ FOR_RULELITERALS(p, dp, rr)
+ if (p > 0 && solv->decisionmap[p] > 0)
+ return; /* false alarm */
+ /* check update/feature rule */
+ p = solv->bestrules_pkg[why - solv->bestrules];
+ if (p < 0)
+ {
+ /* install job */
+ queue_push(solutionq, 0);
+ queue_push(solutionq, solv->ruletojob.elements[-p - solv->jobrules] + 1);
+ return;
+ }
+ rr = solv->rules + solv->featurerules + (p - solv->installed->start);
+ if (!rr->p)
+ rr = solv->rules + solv->updaterules + (p - solv->installed->start);
+ mvrp = 0; /* multi-version replacement */
+ FOR_RULELITERALS(rp, dp, rr)
+ if (rp > 0 && solv->decisionmap[rp] > 0)
+ {
+ mvrp = rp;
+ if (!(solv->noobsoletes.size && MAPTST(&solv->noobsoletes, rp)))
+ break;
+ }
+ if (!rp && mvrp)
+ {
+ queue_push(solutionq, SOLVER_SOLUTION_BEST); /* split, see above */
+ queue_push(solutionq, mvrp);
+ queue_push(solutionq, p);
+ queue_push(solutionq, 0);
+ return;
+ }
+ if (rp)
+ {
+ queue_push(solutionq, SOLVER_SOLUTION_BEST);
+ queue_push(solutionq, rp);
+ }
+ return;
+ }
}
/*
* -> add (SOLVER_INSTALL|SOLVER_SOLVABLE, rp) to the job
* SOLVER_SOLUTION_DISTUPGRADE pkgid
* -> add (SOLVER_INSTALL|SOLVER_SOLVABLE, rp) to the job
+ * SOLVER_SOLUTION_BEST pkgid
+ * -> add (SOLVER_INSTALL|SOLVER_SOLVABLE, rp) to the job
* SOLVER_SOLUTION_JOB jobidx
* -> remove job (jobidx - 1, jobidx) from job queue
* pkgid (> 0) 0
assert(rid > 0);
if (rid >= solv->learntrules)
findproblemrule_internal(solv, solv->learnt_why.elements[rid - solv->learntrules], &lreqr, &lconr, &lsysr, &ljobr);
- else if ((rid >= solv->jobrules && rid < solv->jobrules_end) || (rid >= solv->infarchrules && rid < solv->infarchrules_end) || (rid >= solv->duprules && rid < solv->duprules_end))
+ else if ((rid >= solv->jobrules && rid < solv->jobrules_end) || (rid >= solv->infarchrules && rid < solv->infarchrules_end) || (rid >= solv->duprules && rid < solv->duprules_end) || (rid >= solv->bestrules && rid < solv->bestrules_end))
{
if (!*jobrp)
*jobrp = rid;
#define SOLVER_SOLUTION_JOB (0)
#define SOLVER_SOLUTION_DISTUPGRADE (-1)
#define SOLVER_SOLUTION_INFARCH (-2)
+#define SOLVER_SOLUTION_BEST (-3)
void solver_disableproblem(struct _Solver *solv, Id v);
void solver_enableproblem(struct _Solver *solv, Id v);
}
qs.count = j;
}
+ else if (p != -SYSTEMSOLVABLE)
+ {
+ /* could fallthrough, but then we would do pool_queuetowhatprovides twice */
+ queue_free(&qs);
+ solver_addrule(solv, p, d); /* allow update of s */
+ return;
+ }
}
if (qs.count && p == -SYSTEMSOLVABLE)
p = queue_shift(&qs);
r = solv->rules + solv->featurerules + (p - solv->installed->start);
if (r->p && r->d >= 0)
solver_disablerule(solv, r);
+ if (solv->bestrules_pkg)
+ {
+ int i, ni;
+ ni = solv->bestrules_end - solv->bestrules;
+ for (i = 0; i < ni; i++)
+ if (solv->bestrules_pkg[i] == p)
+ solver_disablerule(solv, solv->rules + solv->bestrules + i);
+ }
}
static inline void
r = solv->rules + solv->updaterules + (p - solv->installed->start);
if (r->p)
{
- if (r->d >= 0)
- return;
- solver_enablerule(solv, r);
- IF_POOLDEBUG (SOLV_DEBUG_SOLUTIONS)
+ if (r->d > 0)
{
- POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "@@@ re-enabling ");
- solver_printruleclass(solv, SOLV_DEBUG_SOLUTIONS, r);
+ solver_enablerule(solv, r);
+ IF_POOLDEBUG (SOLV_DEBUG_SOLUTIONS)
+ {
+ POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "@@@ re-enabling ");
+ solver_printruleclass(solv, SOLV_DEBUG_SOLUTIONS, r);
+ }
}
- return;
}
- r = solv->rules + solv->featurerules + (p - solv->installed->start);
- if (r->p && r->d < 0)
+ else
{
- solver_enablerule(solv, r);
- IF_POOLDEBUG (SOLV_DEBUG_SOLUTIONS)
+ r = solv->rules + solv->featurerules + (p - solv->installed->start);
+ if (r->p && r->d < 0)
{
- POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "@@@ re-enabling ");
- solver_printruleclass(solv, SOLV_DEBUG_SOLUTIONS, r);
+ solver_enablerule(solv, r);
+ IF_POOLDEBUG (SOLV_DEBUG_SOLUTIONS)
+ {
+ POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "@@@ re-enabling ");
+ solver_printruleclass(solv, SOLV_DEBUG_SOLUTIONS, r);
+ }
}
}
+ if (solv->bestrules_pkg)
+ {
+ int i, ni;
+ ni = solv->bestrules_end - solv->bestrules;
+ for (i = 0; i < ni; i++)
+ if (solv->bestrules_pkg[i] == p)
+ solver_enablerule(solv, solv->rules + solv->bestrules + i);
+ }
}
Queue *job = &solv->job;
Pool *pool = solv->pool;
Repo *repo;
+ Repo *installed = solv->installed;
Id select, how, what, p, pi, pp, pip, obs, *obsp;
Solvable *s, *ps;
int i;
{
int haveinstalled;
p = 0;
- if (solv->installed)
+ if (installed)
{
FOR_JOB_SELECT(p, pp, select, what)
- if (pool->solvables[p].repo == solv->installed)
+ if (pool->solvables[p].repo == installed)
break;
}
haveinstalled = p != 0;
Solvable *s = pool->solvables + p;
if (!s->repo)
continue;
- if (haveinstalled && s->repo != solv->installed)
+ if (haveinstalled && s->repo != installed)
continue;
- if (s->repo != solv->installed && !pool_installable(pool, s))
+ if (s->repo != installed && !pool_installable(pool, s))
continue;
MAPSET(&solv->dupinvolvedmap, p);
if (!haveinstalled)
if (ps->name != s->name)
continue;
MAPSET(&solv->dupinvolvedmap, pi);
- if (haveinstalled && ps->repo != solv->installed)
+ if (ps->repo == installed && (how & SOLVER_FORCEBEST) != 0)
+ {
+ if (!solv->bestupdatemap.size)
+ map_grow(&solv->bestupdatemap, installed->end - installed->start);
+ MAPSET(&solv->bestupdatemap, pi - installed->start);
+ }
+ if (haveinstalled && ps->repo != installed)
MAPSET(&solv->dupmap, pi);
}
if (haveinstalled)
{
- if (solv->obsoletes && solv->obsoletes[p - solv->installed->start])
+ if (solv->obsoletes && solv->obsoletes[p - installed->start])
{
Id *opp;
- for (opp = solv->obsoletes_data + solv->obsoletes[p - solv->installed->start]; (pi = *opp++) != 0;)
+ for (opp = solv->obsoletes_data + solv->obsoletes[p - installed->start]; (pi = *opp++) != 0;)
{
ps = pool->solvables + pi;
- if (ps->repo == solv->installed)
+ if (ps->repo == installed)
continue;
MAPSET(&solv->dupinvolvedmap, pi);
MAPSET(&solv->dupmap, pi);
{
FOR_PROVIDES(pi, pp, obs)
{
- Solvable *pis = pool->solvables + pi;
- if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, pis, obs))
+ Solvable *ps = pool->solvables + pi;
+ if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, ps, obs))
continue;
- if (pool->obsoleteusescolors && !pool_colormatch(pool, s, pis))
+ if (pool->obsoleteusescolors && !pool_colormatch(pool, s, ps))
continue;
MAPSET(&solv->dupinvolvedmap, pi);
+ if (ps->repo == installed && (how & SOLVER_FORCEBEST) != 0)
+ {
+ if (!solv->bestupdatemap.size)
+ map_grow(&solv->bestupdatemap, installed->end - installed->start);
+ MAPSET(&solv->bestupdatemap, pi - installed->start);
+ }
}
}
}
repo = pool_id2repo(pool, what);
FOR_REPO_SOLVABLES(repo, p, s)
{
- if (repo != solv->installed && !pool_installable(pool, s))
+ if (repo != installed && !pool_installable(pool, s))
continue;
MAPSET(&solv->dupmap, p);
FOR_PROVIDES(pi, pip, s->name)
if (ps->name != s->name)
continue;
MAPSET(&solv->dupinvolvedmap, pi);
+ if (ps->repo == installed && (how & SOLVER_FORCEBEST) != 0)
+ {
+ if (!solv->bestupdatemap.size)
+ map_grow(&solv->bestupdatemap, installed->end - installed->start);
+ MAPSET(&solv->bestupdatemap, pi - installed->start);
+ }
}
if (s->obsoletes)
{
{
FOR_PROVIDES(pi, pp, obs)
{
- Solvable *pis = pool->solvables + pi;
- if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, pis, obs))
+ Solvable *ps = pool->solvables + pi;
+ if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, ps, obs))
continue;
- if (pool->obsoleteusescolors && !pool_colormatch(pool, s, pis))
+ if (pool->obsoleteusescolors && !pool_colormatch(pool, s, ps))
continue;
MAPSET(&solv->dupinvolvedmap, pi);
+ if (ps->repo == installed && (how & SOLVER_FORCEBEST) != 0)
+ {
+ if (!solv->bestupdatemap.size)
+ map_grow(&solv->bestupdatemap, installed->end - installed->start);
+ MAPSET(&solv->bestupdatemap, pi - installed->start);
+ }
}
}
}
*depp = pool->solvables[-r->p].name;
return SOLVER_RULE_INFARCH;
}
+ if (rid >= solv->bestrules && rid < solv->bestrules_end)
+ {
+ return SOLVER_RULE_BEST;
+ }
if (rid >= solv->choicerules && rid < solv->choicerules_end)
{
return SOLVER_RULE_CHOICE;
return SOLVER_RULE_DISTUPGRADE;
if (rid >= solv->infarchrules && rid < solv->infarchrules_end)
return SOLVER_RULE_INFARCH;
+ if (rid >= solv->bestrules && rid < solv->bestrules_end)
+ return SOLVER_RULE_BEST;
if (rid >= solv->choicerules && rid < solv->choicerules_end)
return SOLVER_RULE_CHOICE;
if (rid >= solv->learntrules)
}
}
+void
+solver_addbestrules(Solver *solv, int havebestinstalljobs)
+{
+ Pool *pool = solv->pool;
+ Id p;
+ Solvable *s;
+ Repo *installed = solv->installed;
+ Queue q, q2;
+ Rule *r;
+ Queue r2pkg;
+ int i, oldcnt;
+
+ solv->bestrules = solv->nrules;
+ if (!installed)
+ {
+ solv->bestrules_end = solv->nrules;
+ return;
+ }
+ queue_init(&q);
+ queue_init(&q2);
+ queue_init(&r2pkg);
+
+ if (havebestinstalljobs)
+ {
+ for (i = 0; i < solv->job.count; i += 2)
+ {
+ if ((solv->job.elements[i] & (SOLVER_JOBMASK | SOLVER_FORCEBEST)) == (SOLVER_INSTALL | SOLVER_FORCEBEST))
+ {
+ int j;
+ Id p2, *pp2;
+ for (j = 0; j < solv->ruletojob.count; j++)
+ if (solv->ruletojob.elements[j] == i)
+ break;
+ if (j == solv->ruletojob.count)
+ continue;
+ r = solv->rules + solv->jobrules + j;
+ queue_empty(&q);
+ FOR_RULELITERALS(p2, pp2, r)
+ if (p2 > 0)
+ queue_push(&q, p2);
+ if (!q.count)
+ continue; /* orphaned */
+ /* select best packages, just look at prio and version */
+ oldcnt = q.count;
+ policy_filter_unwanted(solv, &q, POLICY_MODE_RECOMMEND);
+ if (q.count == oldcnt)
+ continue; /* nothing filtered */
+ p2 = queue_shift(&q);
+ solver_addrule(solv, p2, q.count ? pool_queuetowhatprovides(pool, &q) : 0);
+ queue_push(&r2pkg, -(solv->jobrules + j));
+ }
+ }
+ }
+
+ if (solv->bestupdatemap_all || solv->bestupdatemap.size)
+ {
+ FOR_REPO_SOLVABLES(installed, p, s)
+ {
+ Id d, p2, *pp2;
+ if (!solv->updatemap_all && (!solv->updatemap.size || !MAPTST(&solv->updatemap, p - installed->start)))
+ continue;
+ if (!solv->bestupdatemap_all && (!solv->bestupdatemap.size || !MAPTST(&solv->bestupdatemap, p - installed->start)))
+ continue;
+ queue_empty(&q);
+ if (solv->bestobeypolicy)
+ r = solv->rules + solv->updaterules + (p - installed->start);
+ else
+ {
+ r = solv->rules + solv->featurerules + (p - installed->start);
+ if (!r->p) /* identical to update rule? */
+ r = solv->rules + solv->updaterules + (p - installed->start);
+ }
+ if (solv->multiversionupdaters && (d = solv->multiversionupdaters[p - installed->start]) != 0 && r == solv->rules + solv->updaterules + (p - installed->start))
+ {
+ /* need to check multiversionupdaters */
+ if (r->p == p) /* be careful with the dup case */
+ queue_push(&q, p);
+ while ((p2 = pool->whatprovidesdata[d++]) != 0)
+ queue_push(&q, p2);
+ }
+ else
+ {
+ FOR_RULELITERALS(p2, pp2, r)
+ if (p2 > 0)
+ queue_push(&q, p2);
+ }
+ /* select best packages, just look at prio and version */
+ oldcnt = q.count;
+ policy_filter_unwanted(solv, &q, POLICY_MODE_RECOMMEND);
+ if (!q.count)
+ continue; /* orphaned */
+ if (solv->bestobeypolicy)
+ {
+ /* also filter the best of the feature rule packages and add them */
+ r = solv->rules + solv->featurerules + (p - installed->start);
+ if (r->p)
+ {
+ int j;
+ queue_empty(&q2);
+ FOR_RULELITERALS(p2, pp2, r)
+ if (p2 > 0)
+ queue_push(&q2, p2);
+ policy_filter_unwanted(solv, &q2, POLICY_MODE_RECOMMEND);
+ for (j = 0; j < q2.count; j++)
+ queue_pushunique(&q, q2.elements[j]);
+ }
+ }
+ p2 = queue_shift(&q);
+ solver_addrule(solv, p2, q.count ? pool_queuetowhatprovides(pool, &q) : 0);
+ queue_push(&r2pkg, p);
+ }
+ }
+ if (r2pkg.count)
+ {
+ solv->bestrules_pkg = solv_calloc(r2pkg.count, sizeof(Id));
+ memcpy(solv->bestrules_pkg, r2pkg.elements, r2pkg.count * sizeof(Id));
+ }
+ solv->bestrules_end = solv->nrules;
+ queue_free(&q);
+ queue_free(&q2);
+ queue_free(&r2pkg);
+}
+
#undef CLEANDEPSDEBUG
/*
SOLVER_RULE_DISTUPGRADE = 0x500,
SOLVER_RULE_INFARCH = 0x600,
SOLVER_RULE_CHOICE = 0x700,
- SOLVER_RULE_LEARNT = 0x800
+ SOLVER_RULE_LEARNT = 0x800,
+ SOLVER_RULE_BEST = 0x900
} SolverRuleinfo;
#define SOLVER_RULE_TYPEMASK 0xff00
extern void solver_addchoicerules(struct _Solver *solv);
extern void solver_disablechoicerules(struct _Solver *solv, Rule *r);
+/* best rules */
+extern void solver_addbestrules(struct _Solver *solv, int havebestinstalljobs);
+
/* policy rule disabling/reenabling */
extern void solver_disablepolicyrules(struct _Solver *solv);
extern void solver_reenablepolicyrules(struct _Solver *solv, int jobidx);
map_free(&solv->noobsoletes);
map_free(&solv->updatemap);
+ map_free(&solv->bestupdatemap);
map_free(&solv->fixmap);
map_free(&solv->dupmap);
map_free(&solv->dupinvolvedmap);
solv_free(solv->obsoletes_data);
solv_free(solv->multiversionupdaters);
solv_free(solv->choicerules_ref);
+ solv_free(solv->bestrules_pkg);
solv_free(solv);
}
return solv->noinfarchcheck;
case SOLVER_FLAG_KEEP_EXPLICIT_OBSOLETES:
return solv->keepexplicitobsoletes;
+ case SOLVER_FLAG_BEST_OBEY_POLICY:
+ return solv->bestobeypolicy;
default:
break;
}
case SOLVER_FLAG_KEEP_EXPLICIT_OBSOLETES:
solv->keepexplicitobsoletes = value;
break;
+ case SOLVER_FLAG_BEST_OBEY_POLICY:
+ solv->bestobeypolicy = value;
+ break;
default:
break;
}
}
static void
-add_update_target(Solver *solv, Id p)
+add_update_target(Solver *solv, Id p, Id how)
{
Pool *pool = solv->pool;
Solvable *s = pool->solvables + p;
Solvable *si = pool->solvables + pi;
if (si->repo != installed || si->name != s->name)
continue;
+ if (how & SOLVER_FORCEBEST)
+ {
+ if (!solv->bestupdatemap.size)
+ map_grow(&solv->bestupdatemap, installed->end - installed->start);
+ MAPSET(&solv->bestupdatemap, pi - installed->start);
+ }
queue_push2(solv->update_targets, pi, p);
/* check if it's ok to keep the installed package */
if (s->evr == si->evr && solvable_identical(s, si))
continue;
if (pool->obsoleteusescolors && !pool_colormatch(pool, s, si))
continue;
+ if (how & SOLVER_FORCEBEST)
+ {
+ if (!solv->bestupdatemap.size)
+ map_grow(&solv->bestupdatemap, installed->end - installed->start);
+ MAPSET(&solv->bestupdatemap, pi - installed->start);
+ }
queue_push2(solv->update_targets, pi, p);
}
}
Rule *r;
int now, solve_start;
int hasdupjob = 0;
+ int hasbestinstalljob = 0;
solve_start = solv_timems(0);
break;
case SOLVER_UPDATE:
if (select == SOLVER_SOLVABLE_ALL || (select == SOLVER_SOLVABLE_REPO && installed && what == installed->repoid))
- solv->updatemap_all = 1;
+ {
+ solv->updatemap_all = 1;
+ if (how & SOLVER_FORCEBEST)
+ solv->bestupdatemap_all = 1;
+ }
else if (select == SOLVER_SOLVABLE_REPO && what != installed->repoid)
{
Repo *repo = pool_id2repo(pool, what);
break;
/* targeted update */
FOR_REPO_SOLVABLES(repo, p, s)
- add_update_target(solv, p);
+ add_update_target(solv, p, how);
}
else
{
if (!solv->updatemap.size)
map_grow(&solv->updatemap, installed->end - installed->start);
MAPSET(&solv->updatemap, p - installed->start);
+ if (how & SOLVER_FORCEBEST)
+ {
+ if (!solv->bestupdatemap.size)
+ map_grow(&solv->bestupdatemap, installed->end - installed->start);
+ MAPSET(&solv->bestupdatemap, p - installed->start);
+ }
targeted = 0;
}
if (targeted)
{
FOR_JOB_SELECT(p, pp, select, what)
- add_update_target(solv, p);
+ add_update_target(solv, p, how);
}
}
break;
{
solv->dupmap_all = 1;
solv->updatemap_all = 1;
+ if (how & SOLVER_FORCEBEST)
+ solv->bestupdatemap_all = 1;
}
if (!solv->dupmap_all)
hasdupjob = 1;
d = !q.count ? 0 : pool_queuetowhatprovides(pool, &q); /* internalize */
}
solver_addjobrule(solv, p, d, i, weak);
+ if (how & SOLVER_FORCEBEST)
+ hasbestinstalljob = 1;
break;
case SOLVER_ERASE:
POOL_DEBUG(SOLV_DEBUG_JOB, "job: %s%serase %s\n", weak ? "weak " : "", how & SOLVER_CLEANDEPS ? "clean deps " : "", solver_select2str(pool, select, what));
else
solv->duprules = solv->duprules_end = solv->nrules;
+ if (solv->bestupdatemap_all || solv->bestupdatemap.size || hasbestinstalljob)
+ solver_addbestrules(solv, hasbestinstalljob);
+ else
+ solv->bestrules = solv->bestrules_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
map_free(&installcandidatemap);
queue_free(&q);
- POOL_DEBUG(SOLV_DEBUG_STATS, "%d rpm rules, 2 * %d update rules, %d job rules, %d infarch rules, %d dup rules, %d choice rules\n", solv->rpmrules_end - 1, solv->updaterules_end - solv->updaterules, solv->jobrules_end - solv->jobrules, solv->infarchrules_end - solv->infarchrules, solv->duprules_end - solv->duprules, solv->choicerules_end - solv->choicerules);
+ POOL_DEBUG(SOLV_DEBUG_STATS, "%d rpm rules, 2 * %d update rules, %d job rules, %d infarch rules, %d dup rules, %d choice rules, %d best rules\n", solv->rpmrules_end - 1, solv->updaterules_end - solv->updaterules, solv->jobrules_end - solv->jobrules, solv->infarchrules_end - solv->infarchrules, solv->duprules_end - solv->duprules, solv->choicerules_end - solv->choicerules, solv->bestrules_end - solv->bestrules);
POOL_DEBUG(SOLV_DEBUG_STATS, "overall rule memory used: %d K\n", solv->nrules * (int)sizeof(Rule) / 1024);
/* create weak map */
Id duprules; /* dist upgrade rules */
Id duprules_end;
+ Id bestrules; /* rules from SOLVER_FORCEBEST */
+ Id bestrules_end;
+ Id *bestrules_pkg;
+
Id choicerules; /* choice rules (always weak) */
Id choicerules_end;
Id *choicerules_ref;
Map updatemap; /* bring these installed packages to the newest version */
int updatemap_all; /* bring all packages to the newest version */
+ Map bestupdatemap; /* create best rule for those packages */
+ int bestupdatemap_all; /* bring all packages to the newest version */
+
Map fixmap; /* fix these packages */
int fixmap_all; /* fix all packages */
int noinfarchcheck; /* true: do not forbid inferior architectures */
int keepexplicitobsoletes; /* true: honor obsoletes during multiinstall */
+ int bestobeypolicy; /* true: stay in policy with the best rules */
Map dupmap; /* dup these packages*/
#define SOLVER_FLAG_NO_INFARCHCHECK 9
#define SOLVER_FLAG_ALLOW_NAMECHANGE 10
#define SOLVER_FLAG_KEEP_EXPLICIT_OBSOLETES 11
+#define SOLVER_FLAG_BEST_OBEY_POLICY 12
extern Solver *solver_create(Pool *pool);
extern void solver_free(Solver *solv);
POOL_DEBUG(type, "WEAK ");
if (solv->learntrules && p >= solv->learntrules)
POOL_DEBUG(type, "LEARNT ");
+ else if (p >= solv->bestrules && p < solv->bestrules_end)
+ POOL_DEBUG(type, "BEST ");
else if (p >= solv->choicerules && p < solv->choicerules_end)
POOL_DEBUG(type, "CHOICE ");
else if (p >= solv->infarchrules && p < solv->infarchrules_end)
case SOLVER_RULE_FEATURE:
case SOLVER_RULE_LEARNT:
case SOLVER_RULE_CHOICE:
+ case SOLVER_RULE_BEST:
POOL_DEBUG(SOLV_DEBUG_RESULT, "bad rule type\n");
return;
}
else
POOL_DEBUG(SOLV_DEBUG_RESULT, " - install %s from excluded repository\n", pool_solvable2str(pool, s));
}
+ else if (p == SOLVER_SOLUTION_BEST)
+ {
+ s = pool->solvables + rp;
+ if (solv->installed && s->repo == solv->installed)
+ POOL_DEBUG(SOLV_DEBUG_RESULT, " - keep old %s\n", pool_solvable2str(pool, s));
+ else
+ POOL_DEBUG(SOLV_DEBUG_RESULT, " - install %s despite the old version\n", pool_solvable2str(pool, s));
+ }
else
{
/* policy, replace p with rp */
else
return pool_tmpjoin(pool, "install ", pool_solvable2str(pool, s), " from excluded repository");
}
+ else if (p == SOLVER_SOLUTION_BEST)
+ {
+ Solvable *s = pool->solvables + rp;
+ if (solv->installed && s->repo == solv->installed)
+ return pool_tmpjoin(pool, "keep old ", pool_solvable2str(pool, s), 0);
+ else
+ return pool_tmpjoin(pool, "install ", pool_solvable2str(pool, s), " despite the old version");
+ }
else if (p > 0 && rp == 0)
return pool_tmpjoin(pool, "allow deinstallation of ", pool_solvid2str(pool, p), 0);
else if (p > 0 && rp > 0)