Skip to content

Commit

Permalink
implement strict repo priority
Browse files Browse the repository at this point in the history
add specific rule
add solver flag
add problem message/debug
  • Loading branch information
adriendelsalle committed Aug 9, 2021
1 parent 3d88b0c commit 91be77e
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 11 deletions.
25 changes: 18 additions & 7 deletions src/problems.c
Original file line number Diff line number Diff line change
Expand Up @@ -1068,10 +1068,10 @@ solver_take_solution(Solver *solv, Id problem, Id solution, Queue *job)
*/

static void
findproblemrule_internal(Solver *solv, Id idx, Id *reqrp, Id *conrp, Id *sysrp, Id *jobrp, Id *blkrp, Map *rseen)
findproblemrule_internal(Solver *solv, Id idx, Id *reqrp, Id *conrp, Id *sysrp, Id *jobrp, Id *blkrp, Id *scprp, Map *rseen)
{
Id rid, d;
Id lreqr, lconr, lsysr, ljobr, lblkr;
Id lreqr, lconr, lsysr, ljobr, lblkr, lscpr;
Rule *r;
Id jobassert = 0;
int i, reqset = 0; /* 0: unset, 1: installed, 2: jobassert, 3: assert */
Expand All @@ -1093,7 +1093,7 @@ findproblemrule_internal(Solver *solv, Id idx, Id *reqrp, Id *conrp, Id *sysrp,

/* the problem rules are somewhat ordered from "near to the problem" to
* "near to the job" */
lreqr = lconr = lsysr = ljobr = lblkr = 0;
lreqr = lconr = lsysr = ljobr = lblkr = lscpr = 0;
while ((rid = solv->learnt_pool.elements[idx++]) != 0)
{
assert(rid > 0);
Expand All @@ -1102,7 +1102,7 @@ findproblemrule_internal(Solver *solv, Id idx, Id *reqrp, Id *conrp, Id *sysrp,
if (MAPTST(rseen, rid - solv->learntrules))
continue;
MAPSET(rseen, rid - solv->learntrules);
findproblemrule_internal(solv, solv->learnt_why.elements[rid - solv->learntrules], &lreqr, &lconr, &lsysr, &ljobr, &lblkr, rseen);
findproblemrule_internal(solv, solv->learnt_why.elements[rid - solv->learntrules], &lreqr, &lconr, &lsysr, &ljobr, &lblkr, &lscpr, rseen);
}
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) || (rid >= solv->yumobsrules && rid < solv->yumobsrules_end))
{
Expand All @@ -1119,6 +1119,11 @@ findproblemrule_internal(Solver *solv, Id idx, Id *reqrp, Id *conrp, Id *sysrp,
if (!*blkrp)
*blkrp = rid;
}
else if (rid >= solv->strictrepopriorules && rid < solv->strictrepopriorules_end)
{
if (!*scprp)
*scprp = rid;
}
else
{
assert(rid < solv->pkgrules_end);
Expand Down Expand Up @@ -1183,6 +1188,8 @@ findproblemrule_internal(Solver *solv, Id idx, Id *reqrp, Id *conrp, Id *sysrp,
*sysrp = lsysr;
if (!*blkrp && lblkr)
*blkrp = lblkr;
if (!*scprp && lscpr)
*scprp = lscpr;
}

/*
Expand All @@ -1197,12 +1204,12 @@ findproblemrule_internal(Solver *solv, Id idx, Id *reqrp, Id *conrp, Id *sysrp,
Id
solver_findproblemrule(Solver *solv, Id problem)
{
Id reqr, conr, sysr, jobr, blkr;
Id reqr, conr, sysr, jobr, blkr, srpr;
Id idx = solv->problems.elements[2 * problem - 2];
Map rseen;
reqr = conr = sysr = jobr = blkr = 0;
reqr = conr = sysr = jobr = blkr = srpr = 0;
map_init(&rseen, solv->learntrules ? solv->nrules - solv->learntrules : 0);
findproblemrule_internal(solv, idx, &reqr, &conr, &sysr, &jobr, &blkr, &rseen);
findproblemrule_internal(solv, idx, &reqr, &conr, &sysr, &jobr, &blkr, &srpr, &rseen);
map_free(&rseen);
/* check if the request is about a not-installed package requiring a installed
* package conflicting with the non-installed package. In that case return the conflict */
Expand Down Expand Up @@ -1232,6 +1239,8 @@ solver_findproblemrule(Solver *solv, Id problem)
return conr; /* some conflict */
if (blkr)
return blkr; /* a blacklisted package */
if (srpr)
return srpr; /* a strict repo priority */
if (sysr)
return sysr; /* an update rule */
if (jobr)
Expand Down Expand Up @@ -1350,6 +1359,8 @@ solver_problemruleinfo2str(Solver *solv, SolverRuleinfo type, Id source, Id targ
return pool_tmpappend(pool, s, pool_dep2str(pool, dep), 0);
case SOLVER_RULE_BLACK:
return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " can only be installed by a direct request");
case SOLVER_RULE_STRICT_REPO_PRIORITY:
return pool_tmpjoin(pool, "package '", pool_solvid2str(pool, source), "' is excluded by strict repo priority");
case SOLVER_RULE_PKG_CONSTRAINS:
s = pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), 0);
s = pool_tmpappend(pool, s, " has constraint ", pool_dep2str(pool, dep));
Expand Down
58 changes: 56 additions & 2 deletions src/rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -2992,6 +2992,12 @@ solver_ruleinfo(Solver *solv, Id rid, Id *fromp, Id *top, Id *depp)
*fromp = -r->p;
return SOLVER_RULE_BLACK;
}
if (rid >= solv->strictrepopriorules && rid < solv->strictrepopriorules_end)
{
if (fromp)
*fromp = -r->p;
return SOLVER_RULE_STRICT_REPO_PRIORITY;
}
if (rid >= solv->choicerules && rid < solv->choicerules_end)
return SOLVER_RULE_CHOICE;
if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end)
Expand Down Expand Up @@ -3028,8 +3034,8 @@ solver_ruleclass(Solver *solv, Id rid)
return SOLVER_RULE_CHOICE;
if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end)
return SOLVER_RULE_RECOMMENDS;
if (rid >= solv->blackrules && rid < solv->blackrules_end)
return SOLVER_RULE_BLACK;
if (rid >= solv->strictrepopriorules && rid < solv->strictrepopriorules_end)
return SOLVER_RULE_STRICT_REPO_PRIORITY;
if (rid >= solv->learntrules && rid < solv->nrules)
return SOLVER_RULE_LEARNT;
return SOLVER_RULE_UNKNOWN;
Expand Down Expand Up @@ -4135,6 +4141,54 @@ solver_addrecommendsrules(Solver *solv)
solv->recommendsrules_end = solv->nrules;
}

/* add rules to exclude solvables provided by lower
* precedence repositories */
void solver_addstrictrepopriorules(struct s_Solver *solv, Map *addedmap)
{
Pool *pool = solv->pool;
Solvable *s;
Id p, p2, pp2;
Map priomap;
int max_prio;

map_init_clone(&priomap, addedmap);
solv->strictrepopriorules = solv->nrules;

FOR_POOL_SOLVABLES(p)
{
if (!MAPTST(&priomap, p))
continue;

s = pool->solvables + p;
max_prio = s->repo->priority;
FOR_PROVIDES(p2, pp2, s->name)
{
Solvable *s2 = pool->solvables + p2;
if (s->name != s2->name)
{
MAPCLR(&priomap, p2);
continue;
}
if (s2->repo->priority > max_prio)
max_prio = s2->repo->priority;
}

FOR_PROVIDES(p2, pp2, s->name)
{
Solvable *s2 = pool->solvables + p2;
if (!MAPTST(&priomap, p2))
continue;
MAPCLR(&priomap, p2);
if (pool->installed && s2->repo == pool->installed)
continue;
if (s2->repo->priority < max_prio)
solver_addrule(solv, -p2, 0, 0);
}
}
solv->strictrepopriorules_end = solv->nrules;
map_free(&priomap);
}

void
solver_breakorphans(Solver *solv)
{
Expand Down
6 changes: 5 additions & 1 deletion src/rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ typedef enum {
SOLVER_RULE_BEST = 0x900,
SOLVER_RULE_YUMOBS = 0xa00,
SOLVER_RULE_RECOMMENDS = 0xb00,
SOLVER_RULE_BLACK = 0xc00
SOLVER_RULE_BLACK = 0xc00,
SOLVER_RULE_STRICT_REPO_PRIORITY = 0xd00
} SolverRuleinfo;

#define SOLVER_RULE_TYPEMASK 0xff00
Expand Down Expand Up @@ -142,6 +143,9 @@ extern void solver_addblackrules(struct s_Solver *solv);
/* recommends rules */
extern void solver_addrecommendsrules(struct s_Solver *solv);

/* channel priority rules */
extern void solver_addstrictrepopriorules(struct s_Solver *solv, Map *addedmap);

/* policy rule disabling/reenabling */
extern void solver_disablepolicyrules(struct s_Solver *solv);
extern void solver_reenablepolicyrules(struct s_Solver *solv, int jobidx);
Expand Down
24 changes: 23 additions & 1 deletion src/solver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,8 @@ solver_get_flag(Solver *solv, int flag)
return solv->install_also_updates;
case SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED:
return solv->only_namespace_recommended;
case SOLVER_FLAG_STRICT_REPO_PRIORITY:
return solv->strict_repo_priority;
default:
break;
}
Expand Down Expand Up @@ -1566,6 +1568,9 @@ solver_set_flag(Solver *solv, int flag, int value)
case SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED:
solv->only_namespace_recommended = value;
break;
case SOLVER_FLAG_STRICT_REPO_PRIORITY:
solv->strict_repo_priority = value;
break;
default:
break;
}
Expand Down Expand Up @@ -4062,6 +4067,11 @@ solver_solve(Solver *solv, Queue *job)
else
solv->recommendsrules = solv->recommendsrules_end = solv->nrules;

if (solv->strict_repo_priority)
solver_addstrictrepopriorules(solv, &addedmap);
else
solv->strictrepopriorules = solv->strictrepopriorules_end = solv->nrules;

if (1)
solver_addchoicerules(solv);
else
Expand All @@ -4077,7 +4087,19 @@ solver_solve(Solver *solv, Queue *job)
map_free(&installcandidatemap);
queue_free(&q);

POOL_DEBUG(SOLV_DEBUG_STATS, "%d pkg rules, 2 * %d update rules, %d job rules, %d infarch rules, %d dup rules, %d choice rules, %d best rules, %d yumobs rules\n", solv->pkgrules_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, solv->yumobsrules_end - solv->yumobsrules);
POOL_DEBUG(SOLV_DEBUG_STATS, "%d pkg rules, 2 * %d update rules, %d job rules, %d infarch rules, %d dup rules, %d choice rules, %d best rules, %d yumobs rules\n"
"%d black rules, %d recommends rules, %d repo priority rules\n",
solv->pkgrules_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,
solv->yumobsrules_end - solv->yumobsrules,
solv->blackrules_end - solv->blackrules,
solv->recommendsrules_end - solv->recommendsrules,
solv->strictrepopriorules_end - solv->strictrepopriorules);
POOL_DEBUG(SOLV_DEBUG_STATS, "overall rule memory used: %d K\n", solv->nrules * (int)sizeof(Rule) / 1024);

/* create weak map */
Expand Down
5 changes: 5 additions & 0 deletions src/solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ struct s_Solver {
Id blackrules; /* rules from blacklisted packages */
Id blackrules_end;

Id strictrepopriorules; /* rules from strict priority repositories */
Id strictrepopriorules_end;

Id choicerules; /* choice rules (always weak) */
Id choicerules_end;
Id *choicerules_info; /* the rule we used to generate the choice rule */
Expand Down Expand Up @@ -175,6 +178,7 @@ struct s_Solver {
int strongrecommends; /* true: create weak rules for recommends */
int install_also_updates; /* true: do not prune install job rules to installed packages */
int only_namespace_recommended; /* true: only install packages recommended by namespace */
int strict_repo_priority; /* true: only use packages from highest precedence/priority */

int process_orphans; /* true: do special orphan processing */
Map dupmap; /* dup to those packages */
Expand Down Expand Up @@ -326,6 +330,7 @@ typedef struct s_Solver Solver;
#define SOLVER_FLAG_STRONG_RECOMMENDS 25
#define SOLVER_FLAG_INSTALL_ALSO_UPDATES 26
#define SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED 27
#define SOLVER_FLAG_STRICT_REPO_PRIORITY 28

#define GET_USERINSTALLED_NAMES (1 << 0) /* package names instead of ids */
#define GET_USERINSTALLED_INVERTED (1 << 1) /* autoinstalled */
Expand Down
2 changes: 2 additions & 0 deletions src/solverdebug.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ solver_printruleclass(Solver *solv, int type, Rule *r)
POOL_DEBUG(type, "YUMOBS ");
else if (p >= solv->blackrules && p < solv->blackrules_end)
POOL_DEBUG(type, "BLACK ");
else if (p >= solv->strictrepopriorules && p < solv->strictrepopriorules_end)
POOL_DEBUG(type, "PRIOS ");
else if (p >= solv->recommendsrules && p < solv->recommendsrules_end)
POOL_DEBUG(type, "RECOMMENDS ");
solver_printrule(solv, type, r);
Expand Down

0 comments on commit 91be77e

Please sign in to comment.