summaryrefslogtreecommitdiff
path: root/src/rules.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rules.c')
-rw-r--r--src/rules.c161
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;