diff options
Diffstat (limited to 'src/rules.c')
-rw-r--r-- | src/rules.c | 128 |
1 files changed, 122 insertions, 6 deletions
diff --git a/src/rules.c b/src/rules.c index 212df32..a260c2d 100644 --- a/src/rules.c +++ b/src/rules.c @@ -2257,6 +2257,89 @@ solver_addblackrules(Solver *solv) /*********************************************************************** *** + *** Strict repo prio rule part + ***/ + +/* 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) + continue; + if (s2->repo->priority > max_prio) + max_prio = s2->repo->priority; + } + + FOR_PROVIDES(p2, pp2, s->name) + { + Solvable *s2 = pool->solvables + p2; + if (s->name != s2->name || !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); +} + +static inline void +disablerepopriorule(Solver *solv, Id name) +{ + Pool *pool = solv->pool; + Rule *r; + int i; + for (i = solv->strictrepopriorules, r = solv->rules + i; i < solv->strictrepopriorules_end; i++, r++) + { + if (r->p < 0 && r->d >= 0 && pool->solvables[-r->p].name == name) + solver_disablerule(solv, r); + } +} + +static inline void +reenablerepopriorule(Solver *solv, Id name) +{ + Pool *pool = solv->pool; + Rule *r; + int i; + for (i = solv->strictrepopriorules, r = solv->rules + i; i < solv->strictrepopriorules_end; i++, r++) + { + if (r->p < 0 && r->d < 0 && pool->solvables[-r->p].name == name) + { + solver_enablerule(solv, r); + IF_POOLDEBUG (SOLV_DEBUG_SOLUTIONS) + { + POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "@@@ re-enabling "); + solver_printruleclass(solv, SOLV_DEBUG_SOLUTIONS, r); + } + } + } +} + +/*********************************************************************** + *** *** Policy rule disabling/reenabling *** *** Disable all policy rules that conflict with our jobs. If a job @@ -2264,10 +2347,11 @@ solver_addblackrules(Solver *solv) *** ***/ -#define DISABLE_UPDATE 1 -#define DISABLE_INFARCH 2 -#define DISABLE_DUP 3 -#define DISABLE_BLACK 4 +#define DISABLE_UPDATE 1 +#define DISABLE_INFARCH 2 +#define DISABLE_DUP 3 +#define DISABLE_BLACK 4 +#define DISABLE_REPOPRIO 5 static void jobtodisablelist(Solver *solv, Id how, Id what, Queue *q) @@ -2367,6 +2451,26 @@ jobtodisablelist(Solver *solv, Id how, Id what, Queue *q) } } } + if ((set & SOLVER_SETREPO) != 0 && solv->strictrepopriorules != solv->strictrepopriorules_end) + { + if (select == SOLVER_SOLVABLE) + queue_push2(q, DISABLE_REPOPRIO, pool->solvables[what].name); + else + { + int qcnt = q->count; + FOR_JOB_SELECT(p, pp, select, what) + { + s = pool->solvables + p; + /* unify names */ + for (i = qcnt; i < q->count; i += 2) + if (q->elements[i + 1] == s->name) + break; + if (i < q->count) + continue; + queue_push2(q, DISABLE_REPOPRIO, s->name); + } + } + } if ((set & SOLVER_SETEVR) != 0 && solv->blackrules != solv->blackrules_end) { if (select == SOLVER_SOLVABLE) @@ -2553,6 +2657,9 @@ solver_disablepolicyrules(Solver *solv) case DISABLE_BLACK: disableblackrule(solv, arg); break; + case DISABLE_REPOPRIO: + disablerepopriorule(solv, arg); + break; default: break; } @@ -2659,6 +2766,9 @@ solver_reenablepolicyrules(Solver *solv, int jobidx) case DISABLE_BLACK: reenableblackrule(solv, arg); break; + case DISABLE_REPOPRIO: + reenablerepopriorule(solv, arg); + break; } } queue_free(&q); @@ -2992,6 +3102,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) @@ -3028,8 +3144,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; |