diff options
Diffstat (limited to 'src/rules.c')
-rw-r--r-- | src/rules.c | 161 |
1 files changed, 114 insertions, 47 deletions
diff --git a/src/rules.c b/src/rules.c index df32341..b6cd582 100644 --- a/src/rules.c +++ b/src/rules.c @@ -1463,12 +1463,12 @@ disableupdaterule(Solver *solv, Id p) r = solv->rules + solv->featurerules + (p - solv->installed->start); if (r->p && r->d >= 0) solver_disablerule(solv, r); - if (solv->bestrules_pkg) + if (solv->bestrules_info) { int i, ni; ni = solv->bestrules_end - solv->bestrules; for (i = solv->bestrules_up - solv->bestrules; i < ni; i++) - if (solv->bestrules_pkg[i] == p) + if (solv->bestrules_info[i] == p) solver_disablerule(solv, solv->rules + solv->bestrules + i); } } @@ -1506,12 +1506,12 @@ reenableupdaterule(Solver *solv, Id p) } } } - if (solv->bestrules_pkg) + if (solv->bestrules_info) { int i, ni; ni = solv->bestrules_end - solv->bestrules; for (i = solv->bestrules_up - solv->bestrules; i < ni; i++) - if (solv->bestrules_pkg[i] == p) + if (solv->bestrules_info[i] == p) solver_enablerule(solv, solv->rules + solv->bestrules + i); } } @@ -1674,11 +1674,15 @@ solver_addinfarchrules(Solver *solv, Map *addedmap) } if (installed && pool->solvables[p].repo == installed && !haveinstalled) continue; /* installed package not in lock-step */ + if (lsq.count < 2) + solver_addrule(solv, -p, lsq.count ? lsq.elements[0] : 0, 0); + else + solver_addrule(solv, -p, 0, pool_queuetowhatprovides(pool, &lsq)); } - if (lsq.count < 2) - solver_addrule(solv, -p, lsq.count ? lsq.elements[0] : 0, 0); else - solver_addrule(solv, -p, 0, pool_queuetowhatprovides(pool, &lsq)); + { + solver_addrule(solv, -p, 0, 0); + } } } queue_free(&lsq); @@ -2126,7 +2130,13 @@ jobtodisablelist(Solver *solv, Id how, Id what, Queue *q) if ((set & SOLVER_SETARCH) != 0 && solv->infarchrules != solv->infarchrules_end) { if (select == SOLVER_SOLVABLE) - queue_push2(q, DISABLE_INFARCH, pool->solvables[what].name); + { + for (i = solv->infarchrules; i < solv->infarchrules_end; i++) + if (solv->rules[i].p == -what) + break; + if (i < solv->infarchrules_end) + queue_push2(q, DISABLE_INFARCH, pool->solvables[what].name); + } else { int qcnt = q->count; @@ -2140,8 +2150,12 @@ jobtodisablelist(Solver *solv, Id how, Id what, Queue *q) if (q->elements[i + 1] == s->name) break; if (i < q->count) - continue; - queue_push2(q, DISABLE_INFARCH, s->name); + continue; /* already have that DISABLE_INFARCH element */ + for (i = solv->infarchrules; i < solv->infarchrules_end; i++) + if (solv->rules[i].p == -p) + break; + if (i < solv->infarchrules_end) + queue_push2(q, DISABLE_INFARCH, s->name); } } } @@ -2719,8 +2733,8 @@ solver_ruleinfo(Solver *solv, Id rid, Id *fromp, Id *top, Id *depp) } if (rid >= solv->bestrules && rid < solv->bestrules_end) { - if (fromp && solv->bestrules_pkg[rid - solv->bestrules] > 0) - *fromp = solv->bestrules_pkg[rid - solv->bestrules]; + if (fromp && solv->bestrules_info[rid - solv->bestrules] > 0) + *fromp = solv->bestrules_info[rid - solv->bestrules]; return SOLVER_RULE_BEST; } if (rid >= solv->yumobsrules && rid < solv->yumobsrules_end) @@ -2740,13 +2754,11 @@ solver_ruleinfo(Solver *solv, Id rid, Id *fromp, Id *top, Id *depp) return SOLVER_RULE_YUMOBS; } if (rid >= solv->choicerules && rid < solv->choicerules_end) - { - return SOLVER_RULE_CHOICE; - } + return SOLVER_RULE_CHOICE; + if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end) + return SOLVER_RULE_RECOMMENDS; if (rid >= solv->learntrules) - { - return SOLVER_RULE_LEARNT; - } + return SOLVER_RULE_LEARNT; return SOLVER_RULE_UNKNOWN; } @@ -2773,6 +2785,8 @@ solver_ruleclass(Solver *solv, Id rid) return SOLVER_RULE_YUMOBS; if (rid >= solv->choicerules && rid < solv->choicerules_end) return SOLVER_RULE_CHOICE; + if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end) + return SOLVER_RULE_RECOMMENDS; if (rid >= solv->learntrules && rid < solv->nrules) return SOLVER_RULE_LEARNT; return SOLVER_RULE_UNKNOWN; @@ -2834,7 +2848,9 @@ Id solver_rule2pkgrule(Solver *solv, Id rid) { if (rid >= solv->choicerules && rid < solv->choicerules_end) - return solv->choicerules_ref[rid - solv->choicerules]; + return solv->choicerules_info[rid - solv->choicerules]; + if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end) + return solv->recommendsrules_info[rid - solv->recommendsrules]; return 0; } @@ -2950,7 +2966,7 @@ solver_addchoicerules(Solver *solv) Pool *pool = solv->pool; Map m, mneg; Rule *r; - Queue q, qi, qcheck; + Queue q, qi, qcheck, infoq; int i, j, rid, havechoice; Id p, d, pp; Id p2, pp2; @@ -2966,10 +2982,11 @@ solver_addchoicerules(Solver *solv) return; } now = solv_timems(0); - solv->choicerules_ref = solv_calloc(solv->pkgrules_end, sizeof(Id)); + solv->choicerules_info = solv_calloc(solv->pkgrules_end, sizeof(Id)); queue_init(&q); queue_init(&qi); queue_init(&qcheck); + queue_init(&infoq); map_init(&m, pool->nsolvables); map_init(&mneg, pool->nsolvables); /* set up negative assertion map from infarch and dup rules */ @@ -3158,7 +3175,7 @@ solver_addchoicerules(Solver *solv) solver_addrule(solv, r->p, 0, d); queue_push(&solv->weakruleq, solv->nrules - 1); - solv->choicerules_ref[solv->nrules - 1 - solv->choicerules] = rid; + queue_push(&infoq, rid); #if 0 printf("OLD "); solver_printrule(solv, SOLV_DEBUG_RESULT, solv->rules + rid); @@ -3166,20 +3183,21 @@ solver_addchoicerules(Solver *solv) solver_printrule(solv, SOLV_DEBUG_RESULT, solv->rules + solv->nrules - 1); #endif } + if (infoq.count) + solv->choicerules_info = solv_memdup2(infoq.elements, infoq.count, sizeof(Id)); queue_free(&q); queue_free(&qi); queue_free(&qcheck); + queue_free(&infoq); map_free(&m); map_free(&mneg); solv->choicerules_end = solv->nrules; - /* shrink choicerules_ref */ - solv->choicerules_ref = solv_realloc2(solv->choicerules_ref, solv->choicerules_end - solv->choicerules, sizeof(Id)); POOL_DEBUG(SOLV_DEBUG_STATS, "choice rule creation took %d ms\n", solv_timems(now)); } -/* called when a choice rule is disabled by analyze_unsolvable. We also - * have to disable all other choice rules so that the best packages get - * picked */ +/* called when a choice rule needs to be disabled by analyze_unsolvable. + * We also have to disable all other choice rules so that the best packages + * get picked */ void solver_disablechoicerules(Solver *solv, Rule *r) { @@ -3188,7 +3206,8 @@ solver_disablechoicerules(Solver *solv, Rule *r) Map m; Rule *or; - or = solv->rules + solv->choicerules_ref[(r - solv->rules) - solv->choicerules]; + solver_disablerule(solv, r); + or = solv->rules + solv->choicerules_info[(r - solv->rules) - solv->choicerules]; map_init(&m, pool->nsolvables); FOR_RULELITERALS(p, pp, or) if (p > 0) @@ -3201,7 +3220,7 @@ solver_disablechoicerules(Solver *solv, Rule *r) r = solv->rules + rid; if (r->d < 0) continue; - or = solv->rules + solv->choicerules_ref[(r - solv->rules) - solv->choicerules]; + or = solv->rules + solv->choicerules_info[rid - solv->choicerules]; FOR_RULELITERALS(p, pp, or) if (p > 0 && MAPTST(&m, p)) break; @@ -3250,13 +3269,13 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs) Repo *installed = solv->installed; Queue q, q2; Rule *r; - Queue r2pkg; + Queue infoq; int i, oldcnt; solv->bestrules = solv->nrules; queue_init(&q); queue_init(&q2); - queue_init(&r2pkg); + queue_init(&infoq); if (havebestinstalljobs) { @@ -3297,7 +3316,7 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs) solver_addrule(solv, p2, 0, pool_queuetowhatprovides(pool, &q)); if ((how & SOLVER_WEAK) != 0) queue_push(&solv->weakruleq, solv->nrules - 1); - queue_push(&r2pkg, -(solv->jobrules + j)); + queue_push(&infoq, -(solv->jobrules + j)); } } } @@ -3387,7 +3406,7 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs) solver_addrule(solv, -p2, d, 0); else solver_addrule(solv, -p2, 0, -d); - queue_push(&r2pkg, p); + queue_push(&infoq, p); } for (i = 0; i < q.count; i++) MAPCLR(&m, q.elements[i]); @@ -3398,16 +3417,16 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs) solver_addrule(solv, p2, q.count ? q.elements[0] : 0, 0); else solver_addrule(solv, p2, 0, pool_queuetowhatprovides(pool, &q)); - queue_push(&r2pkg, p); + queue_push(&infoq, p); } map_free(&m); } - if (r2pkg.count) - solv->bestrules_pkg = solv_memdup2(r2pkg.elements, r2pkg.count, sizeof(Id)); + if (infoq.count) + solv->bestrules_info = solv_memdup2(infoq.elements, infoq.count, sizeof(Id)); solv->bestrules_end = solv->nrules; queue_free(&q); queue_free(&q2); - queue_free(&r2pkg); + queue_free(&infoq); } @@ -3442,7 +3461,7 @@ find_obsolete_group(Solver *solv, Id obs, Queue *q) continue; if ((pool->obsoleteusescolors || pool->implicitobsoleteusescolors) && !pool_colormatch(pool, s2, os)) continue; - obsp2 = os->repo->idarraydata + os->obsoletes; + obsp2 = os->repo->idarraydata + os->obsoletes; while ((obs2 = *obsp2++) != 0) if (obs2 == obs) break; @@ -3460,7 +3479,7 @@ find_obsolete_group(Solver *solv, Id obs, Queue *q) continue; if ((pool->obsoleteusescolors || pool->implicitobsoleteusescolors) && !pool_colormatch(pool, s2, os)) continue; - obsp2 = os->repo->idarraydata + os->obsoletes; + obsp2 = os->repo->idarraydata + os->obsoletes; while ((obs2 = *obsp2++) != 0) if (obs2 == obs) break; @@ -3524,7 +3543,7 @@ solver_addyumobsrules(Solver *solv) Repo *installed = solv->installed; Id p, op, *opp; Solvable *s; - Queue qo, qq, yumobsinfoq; + Queue qo, qq, infoq; int i, j, k; unsigned int now; @@ -3570,7 +3589,7 @@ printf("checking yumobs for %s\n", pool_solvable2str(pool, s)); queue_free(&qo); return; } - queue_init(&yumobsinfoq); + queue_init(&infoq); queue_init(&qq); for (i = 0; i < qo.count; i++) { @@ -3588,7 +3607,7 @@ for (j = 0; j < qq.count; j++) else printf("%s\n", pool_solvid2str(pool, qq.elements[j])); #endif - + if (!qq.count) continue; /* at least two goups, build rules */ @@ -3617,22 +3636,70 @@ for (j = 0; j < qq.count; j++) solver_addrule(solv, -p, qq.elements[groupstart], 0); else solver_addrule(solv, -p, 0, pool_ids2whatprovides(pool, qq.elements + groupstart, k - groupstart)); - queue_push(&yumobsinfoq, qo.elements[i]); + queue_push(&infoq, qo.elements[i]); } groupstart = k + 1; groupk++; } } } - if (yumobsinfoq.count) - solv->yumobsrules_info = solv_memdup2(yumobsinfoq.elements, yumobsinfoq.count, sizeof(Id)); - queue_free(&yumobsinfoq); + if (infoq.count) + solv->yumobsrules_info = solv_memdup2(infoq.elements, infoq.count, sizeof(Id)); + queue_free(&infoq); queue_free(&qq); queue_free(&qo); solv->yumobsrules_end = solv->nrules; POOL_DEBUG(SOLV_DEBUG_STATS, "yumobs rule creation took %d ms\n", solv_timems(now)); } +/* recommendsrules are a copy of some recommends package rule but + * with some disfavored literals removed */ +void +solver_addrecommendsrules(Solver *solv) +{ + Pool *pool = solv->pool; + int i, havedis, havepos; + Id p, pp; + Queue q, infoq; + + solv->recommendsrules = solv->nrules; + queue_init(&q); + queue_init(&infoq); + for (i = 0; i < solv->recommendsruleq->count; i++) + { + int rid = solv->recommendsruleq->elements[i]; + Rule *r = solv->rules + rid; + queue_empty(&q); + havedis = havepos = 0; + FOR_RULELITERALS(p, pp, r) + { + if (p > 0 && solv->favormap[p] < 0) + havedis = 1; + else + { + if (p > 0) + havepos = 1; + queue_push(&q, p); + } + } + if (!havedis) + continue; + solver_disablerule(solv, r); + if (!havepos || q.count < 2) + continue; + if (q.count == 2) + solver_addrule(solv, q.elements[0], q.elements[1], 0); + else + solver_addrule(solv, q.elements[0], 0, pool_ids2whatprovides(pool, q.elements + 1, q.count - 1)); + queue_push(&infoq, rid); + } + if (infoq.count) + solv->recommendsrules_info = solv_memdup2(infoq.elements, infoq.count, sizeof(Id)); + queue_free(&infoq); + queue_free(&q); + solv->recommendsrules_end = solv->nrules; +} + void solver_breakorphans(Solver *solv) { @@ -3696,7 +3763,7 @@ solver_check_brokenorphanrules(Solver *solv, Queue *dq) Pool *pool = solv->pool; int i; Id l, pp; - + queue_empty(dq); if (!solv->brokenorphanrules) return; |