summaryrefslogtreecommitdiff
path: root/src/rules.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rules.c')
-rw-r--r--src/rules.c450
1 files changed, 219 insertions, 231 deletions
diff --git a/src/rules.c b/src/rules.c
index c9bbf81..67de769 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -31,7 +31,7 @@
#define RULES_BLOCK 63
-static void addpkgruleinfo(Solver *solv, Id p, Id d, int type, Id dep);
+static void addpkgruleinfo(Solver *solv, Id p, Id p2, Id d, int type, Id dep);
static void solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded);
/*-------------------------------------------------------------------
@@ -66,8 +66,6 @@ dep_possible(Solver *solv, Id dep, Map *m)
}
if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES)
return solver_splitprovides(solv, rd->evr, m);
- if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_INSTALLED)
- return solver_dep_installed(solv, rd->evr);
}
}
FOR_PROVIDES(p, pp, dep)
@@ -243,27 +241,23 @@ hashrule(Solver *solv, Id p, Id d, int n)
/*
* add rule
- * p = direct literal; always < 0 for installed pkg rules
- * d, if < 0 direct literal, if > 0 offset into whatprovides, if == 0 rule is assertion (look at p only)
- *
*
* A requires b, b provided by B1,B2,B3 => (-A|B1|B2|B3)
*
- * p < 0 : pkg id of A
- * d > 0 : Offset in whatprovidesdata (list of providers of b)
+ * p < 0 : pkg id of A
+ * d > 0 : Offset in whatprovidesdata (list of providers of b)
*
* A conflicts b, b provided by B1,B2,B3 => (-A|-B1), (-A|-B2), (-A|-B3)
- * p < 0 : pkg id of A
- * d < 0 : Id of solvable (e.g. B1)
+ * p < 0 : pkg id of A
+ * p2 < 0 : Id of solvable (e.g. B1)
*
- * d == 0: unary rule, assertion => (A) or (-A)
+ * d == 0, p2 == 0: unary rule, assertion => (A) or (-A)
*
* Install: p > 0, d = 0 (A) user requested install
* Remove: p < 0, d = 0 (-A) user requested remove (also: uninstallable)
* Requires: p < 0, d > 0 (-A|B1|B2|...) d: <list of providers for requirement of p>
- * Requires: p > 0, d < 0 (B|-A) hack to save a whatprovides allocation, gets converted into (-A|B)
* Updates: p > 0, d > 0 (A|B1|B2|...) d: <list of updates for solvable p>
- * Conflicts: p < 0, d < 0 (-A|-B) either p (conflict issuer) or d (conflict provider) (binary rule)
+ * Conflicts: p < 0, p2 < 0 (-A|-B) either p (conflict issuer) or d (conflict provider) (binary rule)
* also used for obsoletes
* No-op ?: p = 0, d = 0 (null) (used as placeholder in update/feature rules)
*
@@ -277,118 +271,87 @@ hashrule(Solver *solv, Id p, Id d, int n)
*/
Rule *
-solver_addrule(Solver *solv, Id p, Id d)
+solver_addrule(Solver *solv, Id p, Id p2, Id d)
{
Pool *pool = solv->pool;
- Rule *r = 0;
- Id *dp = 0;
+ Rule *r;
+
+ if (d)
+ {
+ assert(!p2 && d > 0);
+ if (!pool->whatprovidesdata[d])
+ d = 0;
+ else if (!pool->whatprovidesdata[d + 1])
+ {
+ p2 = pool->whatprovidesdata[d];
+ d = 0;
+ }
+ }
- int n = 0; /* number of literals in rule - 1
- 0 = direct assertion (single literal)
- 1 = binary rule
- >1 = multi-literal rule
- */
+ /* now we have two cases:
+ * 1 or 2 literals: d = 0, p, p2 contain the literals
+ * 3 or more literals: d > 0, p2 == 0, d is offset into whatprovidesdata
+ */
/* it often happenes that requires lead to adding the same pkg rule
* multiple times, so we prune those duplicates right away to make
* the work for unifyrules a bit easier */
-
if (!solv->pkgrules_end) /* we add pkg rules */
{
- r = solv->rules + solv->nrules - 1; /* get the last added rule */
- if (r->p == p && r->d == d && (d != 0 || !r->w2))
- return r;
- }
-
- /* compute number of literals (n) in rule */
- if (d < 0)
- {
- if (p == -d)
- return 0; /* rule is self-fulfilling */
- if (p == d)
- d = 0; /* normalize to assertion */
+ r = solv->rules + solv->nrules - 1;
+ if (d)
+ {
+ Id *dp;
+ /* check if rule is identical */
+ if (r->p == p)
+ {
+ Id *dp2;
+ if (r->d == d)
+ return r;
+ dp2 = pool->whatprovidesdata + r->d;
+ for (dp = pool->whatprovidesdata + d; *dp; dp++, dp2++)
+ if (*dp != *dp2)
+ break;
+ if (*dp == *dp2)
+ return r;
+ }
+ /* check if rule is self-fulfilling */
+ for (dp = pool->whatprovidesdata + d; *dp; dp++)
+ if (*dp == -p)
+ return 0; /* rule is self-fulfilling */
+ }
else
- n = 1; /* binary rule */
- }
- else if (d > 0)
- {
- for (dp = pool->whatprovidesdata + d; *dp; dp++, n++)
- if (*dp == -p)
- return 0; /* rule is self-fulfilling */
- if (n == 1) /* convert to binary rule */
- d = dp[-1];
- }
-
- if (n == 1 && p > d && !solv->pkgrules_end)
- {
- /* put smallest literal first so we can find dups */
- n = p; p = d; d = n; /* p <-> d */
- n = 1; /* re-set n, was used as temp var */
- }
-
- /*
- * check for duplicate (r is only set if we're adding pkg rules)
- */
- if (r)
- {
- /* check if the last added rule (r) is exactly the same as what we're looking for. */
- if (n == 1 && !r->d && r->p == p && r->w2 == d)
- return r;
- /* have n-ary rule with same first literal, check other literals */
- if (n > 1 && r->d && r->p == p)
{
- /* Rule where d is an offset in whatprovidesdata */
- Id *dp2;
- if (d == r->d)
- return r;
- dp2 = pool->whatprovidesdata + r->d;
- for (dp = pool->whatprovidesdata + d; *dp; dp++, dp2++)
- if (*dp != *dp2)
- break;
- if (*dp == *dp2)
+ if (p2 && p > p2)
+ {
+ Id o = p; /* switch p1 and p2 */
+ p = p2;
+ p2 = o;
+ }
+ if (r->p == p && !r->d && r->w2 == p2)
return r;
+ if (p == -p2)
+ return 0; /* rule is self-fulfilling */
}
}
- /*
- * allocate new rule r
- */
solv->rules = solv_extend(solv->rules, solv->nrules, 1, sizeof(Rule), RULES_BLOCK);
r = solv->rules + solv->nrules++; /* point to rule space */
-
r->p = p;
- if (n == 0)
- {
- /* direct assertion, no watch needed */
- r->d = 0;
- r->w1 = p;
- r->w2 = 0;
- }
- else if (n == 1)
- {
- /* binary rule */
- r->d = 0;
- r->w1 = p;
- r->w2 = d;
- }
- else
- {
- r->d = d;
- r->w1 = p;
- r->w2 = pool->whatprovidesdata[d];
- }
+ r->d = d;
+ r->w1 = p;
+ r->w2 = d ? pool->whatprovidesdata[d] : p2;
r->n1 = 0;
r->n2 = 0;
-
IF_POOLDEBUG (SOLV_DEBUG_RULE_CREATION)
{
POOL_DEBUG(SOLV_DEBUG_RULE_CREATION, " Add rule: ");
solver_printrule(solv, SOLV_DEBUG_RULE_CREATION, r);
}
-
return r;
}
+
void
solver_shrinkrules(Solver *solv, int nrules)
{
@@ -434,7 +397,7 @@ makemultiversionconflict(Solver *solv, Id n, Id con)
queue_push(&q, p);
}
if (q.count == 1)
- n = -n; /* no other package found, generate normal conflict */
+ n = 0; /* no other package found, normal conflict handling */
else
n = pool_queuetowhatprovides(pool, &q);
queue_free(&q);
@@ -442,12 +405,12 @@ makemultiversionconflict(Solver *solv, Id n, Id con)
}
static inline void
-addpkgrule(Solver *solv, Id p, Id d, int type, Id dep)
+addpkgrule(Solver *solv, Id p, Id p2, Id d, int type, Id dep)
{
if (!solv->ruleinfoq)
- solver_addrule(solv, p, d);
+ solver_addrule(solv, p, p2, d);
else
- addpkgruleinfo(solv, p, d, type, dep);
+ addpkgruleinfo(solv, p, p2, d, type, dep);
}
#ifdef ENABLE_LINKED_PKGS
@@ -469,19 +432,19 @@ addlinks(Solver *solv, Solvable *s, Id req, Queue *qr, Id prv, Queue *qp, Map *m
#endif
if (qr->count == 1)
- addpkgrule(solv, qr->elements[0], -(s - pool->solvables), SOLVER_RULE_PKG_REQUIRES, req);
+ addpkgrule(solv, -(s - pool->solvables), qr->elements[0], 0, SOLVER_RULE_PKG_REQUIRES, req);
else
- addpkgrule(solv, -(s - pool->solvables), pool_queuetowhatprovides(pool, qr), SOLVER_RULE_PKG_REQUIRES, req);
+ addpkgrule(solv, -(s - pool->solvables), 0, pool_queuetowhatprovides(pool, qr), SOLVER_RULE_PKG_REQUIRES, req);
if (qp->count > 1)
{
Id d = pool_queuetowhatprovides(pool, qp);
for (i = 0; i < qr->count; i++)
- addpkgrule(solv, -qr->elements[i], d, SOLVER_RULE_PKG_REQUIRES, prv);
+ addpkgrule(solv, -qr->elements[i], 0, d, SOLVER_RULE_PKG_REQUIRES, prv);
}
else if (qp->count)
{
for (i = 0; i < qr->count; i++)
- addpkgrule(solv, qp->elements[0], -qr->elements[i], SOLVER_RULE_PKG_REQUIRES, prv);
+ addpkgrule(solv, -qr->elements[i], qp->elements[0], 0, SOLVER_RULE_PKG_REQUIRES, prv);
}
if (!m)
return; /* nothing more to do if called from getpkgruleinfos() */
@@ -535,13 +498,16 @@ add_complex_deprules(Solver *solv, Id p, Id dep, int type, int dontfix, Queue *w
{
Pool *pool = solv->pool;
Repo *installed = solv->installed;
- int i, j;
+ int i, j, flags;
Queue bq;
queue_init(&bq);
-
+ flags = dontfix ? CPLXDEPS_DONTFIX : 0;
/* CNF expansion for requires, DNF + INVERT expansion for conflicts */
- i = pool_normalize_complex_dep(pool, dep, &bq, type == SOLVER_RULE_PKG_REQUIRES ? 0 : (CPLXDEPS_TODNF | CPLXDEPS_EXPAND | CPLXDEPS_INVERT));
+ if (type == SOLVER_RULE_PKG_CONFLICTS)
+ flags |= CPLXDEPS_TODNF | CPLXDEPS_EXPAND | CPLXDEPS_INVERT;
+
+ i = pool_normalize_complex_dep(pool, dep, &bq, flags);
/* handle special cases */
if (i == 0)
{
@@ -552,7 +518,7 @@ add_complex_deprules(Solver *solv, Id p, Id dep, int type, int dontfix, Queue *w
else
{
POOL_DEBUG(SOLV_DEBUG_RULE_CREATION, "package %s [%d] is not installable (%s)\n", pool_solvid2str(pool, p), p, pool_dep2str(pool, dep));
- addpkgrule(solv, -p, 0, type == SOLVER_RULE_PKG_REQUIRES ? SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP : type, dep);
+ addpkgrule(solv, -p, 0, 0, type == SOLVER_RULE_PKG_REQUIRES ? SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP : type, dep);
}
queue_free(&bq);
return;
@@ -579,19 +545,15 @@ add_complex_deprules(Solver *solv, Id p, Id dep, int type, int dontfix, Queue *w
if (pool->solvables[dp[j]].repo == installed)
break; /* provider was installed */
if (!dp[j])
- {
- POOL_DEBUG(SOLV_DEBUG_RULE_CREATION, "ignoring broken requires %s of installed package %s\n", pool_dep2str(pool, dep), pool_solvid2str(pool, p));
- continue;
- }
- }
- if (!*dp)
- {
- /* nothing provides req! */
- POOL_DEBUG(SOLV_DEBUG_RULE_CREATION, "package %s [%d] is not installable (%s)\n", pool_solvid2str(pool, p), p, pool_dep2str(pool, dep));
- addpkgrule(solv, -p, 0, SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP, dep);
- continue;
+ continue;
}
- addpkgrule(solv, -p, dp - pool->whatprovidesdata, SOLVER_RULE_PKG_REQUIRES, dep);
+ /* check if the rule contains both p and -p */
+ for (j = 0; dp[j] != 0; j++)
+ if (dp[j] == p)
+ break;
+ if (dp[j])
+ continue;
+ addpkgrule(solv, -p, 0, dp - pool->whatprovidesdata, SOLVER_RULE_PKG_REQUIRES, dep);
/* push all non-visited providers on the work queue */
if (m)
for (; *dp; dp++)
@@ -601,29 +563,30 @@ add_complex_deprules(Solver *solv, Id p, Id dep, int type, int dontfix, Queue *w
}
if (!bq.elements[i + 1])
{
- Id p2 = bq.elements[i];
- /* simple rule with just two literals */
- if (dontfix && p2 < 0 && pool->solvables[-p2].repo == installed)
- continue;
- if (dontfix && p2 > 0 && pool->solvables[p2].repo != installed)
- continue;
- if (p == p2)
- continue;
+ Id p2 = bq.elements[i++];
+ /* simple rule with just two literals, we'll add a (-p, p2) rule */
+ if (dontfix)
+ {
+ if (p2 < 0 && pool->solvables[-p2].repo == installed)
+ continue;
+ if (p2 > 0 && pool->solvables[p2].repo != installed)
+ continue;
+ }
if (-p == p2)
{
if (type == SOLVER_RULE_PKG_CONFLICTS)
{
if (pool->forbidselfconflicts && !is_otherproviders_dep(pool, dep))
- addpkgrule(solv, -p, 0, SOLVER_RULE_PKG_SELF_CONFLICT, dep);
+ addpkgrule(solv, -p, 0, 0, SOLVER_RULE_PKG_SELF_CONFLICT, dep);
continue;
}
- addpkgrule(solv, -p, 0, type, dep);
+ addpkgrule(solv, -p, 0, 0, type, dep);
continue;
}
- if (p2 > 0)
- addpkgrule(solv, p2, -p, type, dep); /* hack so that we don't need pool_queuetowhatprovides */
- else
- addpkgrule(solv, -p, p2, type, dep);
+ /* check if the rule contains both p and -p */
+ if (p == p2)
+ continue;
+ addpkgrule(solv, -p, p2, 0, type, dep);
if (m && p2 > 0 && !MAPTST(m, p2))
queue_push(workq, p2);
}
@@ -667,19 +630,13 @@ add_complex_deprules(Solver *solv, Id p, Id dep, int type, int dontfix, Queue *w
for (j = 0; j < qcnt; j++)
if (qele[j] == p)
break;
- if (j == qcnt)
- {
- /* hack: create fake queue 'q' so that we can call pool_queuetowhatprovides */
- Queue q;
- memset(&q, 0, sizeof(q));
- q.count = qcnt - 1;
- q.elements = qele + 1;
- addpkgrule(solv, qele[0], pool_queuetowhatprovides(pool, &q), type, dep);
- if (m)
- for (j = 0; j < qcnt; j++)
- if (qele[j] > 0 && !MAPTST(m, qele[j]))
- queue_push(workq, qele[j]);
- }
+ if (j < qcnt)
+ continue;
+ addpkgrule(solv, qele[0], 0, pool_ids2whatprovides(pool, qele + 1, qcnt - 1), type, dep);
+ if (m)
+ for (j = 0; j < qcnt; j++)
+ if (qele[j] > 0 && !MAPTST(m, qele[j]))
+ queue_push(workq, qele[j]);
}
}
queue_free(&bq);
@@ -764,7 +721,7 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m)
: !pool_installable(pool, s))
{
POOL_DEBUG(SOLV_DEBUG_RULE_CREATION, "package %s [%d] is not installable\n", pool_solvid2str(pool, n), n);
- addpkgrule(solv, -n, 0, SOLVER_RULE_PKG_NOT_INSTALLABLE, 0);
+ addpkgrule(solv, -n, 0, 0, SOLVER_RULE_PKG_NOT_INSTALLABLE, 0);
}
}
@@ -821,10 +778,16 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m)
if (!*dp)
{
POOL_DEBUG(SOLV_DEBUG_RULE_CREATION, "package %s [%d] is not installable (%s)\n", pool_solvid2str(pool, n), n, pool_dep2str(pool, req));
- addpkgrule(solv, -n, 0, SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP, req);
+ addpkgrule(solv, -n, 0, 0, SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP, req);
continue;
}
+ for (i = 0; dp[i] != 0; i++)
+ if (n == dp[i])
+ break;
+ if (dp[i])
+ continue; /* provided by itself, no need to add rule */
+
IF_POOLDEBUG (SOLV_DEBUG_RULE_CREATION)
{
POOL_DEBUG(SOLV_DEBUG_RULE_CREATION," %s requires %s\n", pool_solvable2str(pool, s), pool_dep2str(pool, req));
@@ -834,7 +797,7 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m)
/* add 'requires' dependency */
/* rule: (-requestor|provider1|provider2|...|providerN) */
- addpkgrule(solv, -n, dp - pool->whatprovidesdata, SOLVER_RULE_PKG_REQUIRES, req);
+ addpkgrule(solv, -n, 0, dp - pool->whatprovidesdata, SOLVER_RULE_PKG_REQUIRES, req);
/* push all non-visited providers on the work queue */
if (m)
@@ -888,16 +851,23 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m)
{
if (!pool->forbidselfconflicts || is_otherproviders_dep(pool, con))
continue;
- addpkgrule(solv, -n, 0, SOLVER_RULE_PKG_SELF_CONFLICT, con);
+ addpkgrule(solv, -n, 0, 0, SOLVER_RULE_PKG_SELF_CONFLICT, con);
continue;
}
if (ispatch && solv->multiversion.size && MAPTST(&solv->multiversion, p) && ISRELDEP(con))
{
/* our patch conflicts with a multiversion package */
- p = -makemultiversionconflict(solv, p, con);
+ Id d = makemultiversionconflict(solv, p, con);
+ if (d)
+ {
+ addpkgrule(solv, -n, 0, d, SOLVER_RULE_PKG_CONFLICTS, con);
+ continue;
+ }
}
+ if (p == SYSTEMSOLVABLE)
+ p = 0;
/* rule: -n|-p: either solvable _or_ provider of conflict */
- addpkgrule(solv, -n, p == SYSTEMSOLVABLE ? 0 : -p, SOLVER_RULE_PKG_CONFLICTS, con);
+ addpkgrule(solv, -n, -p, 0, SOLVER_RULE_PKG_CONFLICTS, con);
}
}
}
@@ -930,10 +900,12 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m)
continue;
if (pool->obsoleteusescolors && !pool_colormatch(pool, s, ps))
continue;
+ if (p == SYSTEMSOLVABLE)
+ p = 0;
if (!isinstalled)
- addpkgrule(solv, -n, -p, SOLVER_RULE_PKG_OBSOLETES, obs);
+ addpkgrule(solv, -n, -p, 0, SOLVER_RULE_PKG_OBSOLETES, obs);
else
- addpkgrule(solv, -n, -p, SOLVER_RULE_PKG_INSTALLED_OBSOLETES, obs);
+ addpkgrule(solv, -n, -p, 0, SOLVER_RULE_PKG_INSTALLED_OBSOLETES, obs);
}
}
}
@@ -959,10 +931,21 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m)
continue;
if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, ps))
continue;
+ if (p == SYSTEMSOLVABLE)
+ p = 0;
if (s->name == ps->name)
- addpkgrule(solv, -n, -p, SOLVER_RULE_PKG_SAME_NAME, 0);
+ {
+ /* optimization: do not add the same-name conflict rule if it was
+ * already added when we looket at the other package.
+ * (this assumes pool_colormatch is symmetric) */
+ if (p && m && ps->repo != installed && MAPTST(m, p) &&
+ (ps->arch != ARCH_SRC && ps->arch != ARCH_NOSRC) &&
+ !(solv->multiversion.size && MAPTST(&solv->multiversion, p)))
+ continue;
+ addpkgrule(solv, -n, -p, 0, SOLVER_RULE_PKG_SAME_NAME, 0);
+ }
else
- addpkgrule(solv, -n, -p, SOLVER_RULE_PKG_IMPLICIT_OBSOLETES, s->name);
+ addpkgrule(solv, -n, -p, 0, SOLVER_RULE_PKG_IMPLICIT_OBSOLETES, s->name);
}
}
}
@@ -1234,7 +1217,7 @@ solver_addupdaterule(Solver *solv, Solvable *s, int allow_all)
{
/* a linked pseudo package. As it is linked, we do not need an update rule */
/* nevertheless we set specialupdaters so we can update */
- solver_addrule(solv, 0, 0);
+ solver_addrule(solv, 0, 0, 0);
if (!allow_all && qs.count)
{
if (p != -SYSTEMSOLVABLE)
@@ -1305,16 +1288,25 @@ solver_addupdaterule(Solver *solv, Solvable *s, int allow_all)
{
/* could fallthrough, but then we would do pool_queuetowhatprovides twice */
queue_free(&qs);
- solver_addrule(solv, p, d); /* allow update of s */
+ solver_addrule(solv, p, 0, d); /* allow update of s */
return;
}
}
}
if (qs.count && p == -SYSTEMSOLVABLE)
p = queue_shift(&qs);
- d = qs.count ? pool_queuetowhatprovides(pool, &qs) : 0;
- queue_free(&qs);
- solver_addrule(solv, p, d); /* allow update of s */
+ if (qs.count > 1)
+ {
+ d = pool_queuetowhatprovides(pool, &qs);
+ queue_free(&qs);
+ solver_addrule(solv, p, 0, d); /* allow update of s */
+ }
+ else
+ {
+ d = qs.count ? qs.elements[0] : 0;
+ queue_free(&qs);
+ solver_addrule(solv, p, d, 0); /* allow update of s */
+ }
}
static inline void
@@ -1543,7 +1535,10 @@ solver_addinfarchrules(Solver *solv, Map *addedmap)
if (installed && pool->solvables[p].repo == installed && !haveinstalled)
continue; /* installed package not in lock-step */
}
- solver_addrule(solv, -p, lsq.count ? pool_queuetowhatprovides(pool, &lsq) : 0);
+ 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));
}
}
queue_free(&lsq);
@@ -1726,6 +1721,15 @@ solver_createdupmaps(Solver *solv)
solver_addtodupmaps(solv, p, how, targeted);
}
}
+ else if (select == SOLVER_SOLVABLE_ALL)
+ {
+ FOR_POOL_SOLVABLES(p)
+ {
+ MAPSET(&solv->dupinvolvedmap, p);
+ if (installed && pool->solvables[p].repo != installed)
+ MAPSET(&solv->dupmap, p);
+ }
+ }
else
{
targeted = how & SOLVER_TARGETED ? 1 : 0;
@@ -1810,13 +1814,13 @@ solver_addduprules(Solver *solv, Map *addedmap)
break;
}
if (!ip)
- solver_addrule(solv, -p, 0); /* no match, sorry */
+ solver_addrule(solv, -p, 0, 0); /* no match, sorry */
else
MAPSET(&solv->dupmap, p); /* for best rules processing */
}
}
else if (!MAPTST(&solv->dupmap, p))
- solver_addrule(solv, -p, 0);
+ solver_addrule(solv, -p, 0, 0);
}
}
solv->duprules_end = solv->nrules;
@@ -2374,34 +2378,30 @@ solver_reenablepolicyrules_cleandeps(Solver *solv, Id pkg)
***/
static void
-addpkgruleinfo(Solver *solv, Id p, Id d, int type, Id dep)
+addpkgruleinfo(Solver *solv, Id p, Id p2, Id d, int type, Id dep)
{
Pool *pool = solv->pool;
Rule *r;
- Id w2, op, od, ow2;
- /* check if this creates the rule we're searching for */
- r = solv->rules + solv->ruleinfoq->elements[0];
- op = r->p;
- od = r->d < 0 ? -r->d - 1 : r->d;
- ow2 = 0;
-
- /* normalize */
- w2 = d > 0 ? 0 : d;
- if (p < 0 && d > 0 && (!pool->whatprovidesdata[d] || !pool->whatprovidesdata[d + 1]))
+ if (d)
{
- w2 = pool->whatprovidesdata[d];
- d = 0;
- }
- if (p > 0 && d < 0) /* this hack is used for package links and complex deps */
- {
- w2 = p;
- p = d;
+ assert(!p2 && d > 0);
+ if (!pool->whatprovidesdata[d])
+ d = 0;
+ else if (!pool->whatprovidesdata[d + 1])
+ {
+ p2 = pool->whatprovidesdata[d];
+ d = 0;
+ }
}
- if (d > 0)
+ /* check if this creates the rule we're searching for */
+ r = solv->rules + solv->ruleinfoq->elements[0];
+ if (d)
{
- if (p != op && !od)
+ /* three or more literals */
+ Id od = r->d < 0 ? -r->d - 1 : r->d;
+ if (p != r->p && !od)
return;
if (d != od)
{
@@ -2413,46 +2413,33 @@ addpkgruleinfo(Solver *solv, Id p, Id d, int type, Id dep)
if (*odp)
return;
}
- w2 = 0;
- /* handle multiversion conflict rules */
- if (p < 0 && pool->whatprovidesdata[d] < 0)
- {
- w2 = pool->whatprovidesdata[d];
- /* XXX: free memory */
- }
+ if (p < 0 && pool->whatprovidesdata[d] < 0 && type == SOLVER_RULE_PKG_CONFLICTS)
+ p2 = pool->whatprovidesdata[d];
}
else
{
- if (od)
- return;
- ow2 = r->w2;
- if (p > w2)
+ /* one or two literals */
+ Id op = p, op2 = p2;
+ if (op2 && op > op2) /* normalize */
{
- if (w2 != op || p != ow2)
- return;
+ Id o = op;
+ op = op2;
+ op2 = o;
}
- else
+ if (r->p != op || r->w2 != op2 || (r->d && r->d != -1))
+ return;
+ if (type == SOLVER_RULE_PKG_CONFLICTS && !p2)
+ p2 = -SYSTEMSOLVABLE;
+ if (type == SOLVER_RULE_PKG_SAME_NAME)
{
- if (p != op || w2 != ow2)
- return;
+ p = op; /* we normalize same name order */
+ p2 = op2;
}
- /* should use a different type instead */
- if (type == SOLVER_RULE_PKG_CONFLICTS && !w2)
- w2 = -SYSTEMSOLVABLE;
}
/* yep, rule matches. record info */
queue_push(solv->ruleinfoq, type);
- if (type == SOLVER_RULE_PKG_SAME_NAME)
- {
- /* we normalize same name order */
- queue_push(solv->ruleinfoq, op < 0 ? -op : 0);
- queue_push(solv->ruleinfoq, ow2 < 0 ? -ow2 : 0);
- }
- else
- {
- queue_push(solv->ruleinfoq, p < 0 ? -p : 0);
- queue_push(solv->ruleinfoq, w2 < 0 ? -w2 : 0);
- }
+ queue_push(solv->ruleinfoq, p < 0 ? -p : 0);
+ queue_push(solv->ruleinfoq, p2 < 0 ? -p2 : 0);
queue_push(solv->ruleinfoq, dep);
}
@@ -2706,7 +2693,7 @@ 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->learntrules)
+ if (rid >= solv->learntrules && rid < solv->nrules)
return SOLVER_RULE_LEARNT;
return SOLVER_RULE_UNKNOWN;
}
@@ -3068,7 +3055,7 @@ solver_addchoicerules(Solver *solv)
lastaddedd = d;
lastaddedcnt = q.count;
- solver_addrule(solv, r->p, d);
+ solver_addrule(solv, r->p, 0, d);
queue_push(&solv->weakruleq, solv->nrules - 1);
solv->choicerules_ref[solv->nrules - 1 - solv->choicerules] = rid;
#if 0
@@ -3200,7 +3187,10 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs)
if (q.count == oldcnt)
continue; /* nothing filtered */
p2 = queue_shift(&q);
- solver_addrule(solv, p2, q.count ? pool_queuetowhatprovides(pool, &q) : 0);
+ if (q.count < 2)
+ solver_addrule(solv, p2, q.count ? q.elements[0] : 0, 0);
+ else
+ solver_addrule(solv, p2, 0, pool_queuetowhatprovides(pool, &q));
queue_push(&r2pkg, -(solv->jobrules + j));
}
}
@@ -3267,7 +3257,10 @@ solver_addbestrules(Solver *solv, int havebestinstalljobs)
}
}
p2 = queue_shift(&q);
- solver_addrule(solv, p2, q.count ? pool_queuetowhatprovides(pool, &q) : 0);
+ if (q.count < 2)
+ 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);
}
}
@@ -3481,11 +3474,10 @@ for (j = 0; j < qq.count; j++)
if (group != groupk && k > groupstart)
{
/* add the rule */
- Queue qhelper;
- memset(&qhelper, 0, sizeof(qhelper));
- qhelper.count = k - groupstart;
- qhelper.elements = qq.elements + groupstart;
- solver_addrule(solv, -p, pool_queuetowhatprovides(pool, &qhelper));
+ if (k - groupstart == 1)
+ 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]);
}
groupstart = k + 1;
@@ -3538,8 +3530,6 @@ dep_pkgcheck(Solver *solv, Id dep, Map *m, Queue *q)
}
if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_SPLITPROVIDES)
return;
- if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_INSTALLED)
- return;
}
}
FOR_PROVIDES(p, pp, dep)
@@ -3576,8 +3566,6 @@ check_xsupp(Solver *solv, Queue *depq, Id dep)
#else
return 0;
#endif
- if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_INSTALLED)
- return solver_dep_installed(solv, rd->evr);
}
if (depq && rd->flags == REL_NAMESPACE)
{
@@ -3783,7 +3771,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
/* have special namespace cleandeps erases */
if (iq.count)
{
- for (ip = solv->installed->start; ip < solv->installed->end; ip++)
+ for (ip = installed->start; ip < installed->end; ip++)
{
s = pool->solvables + ip;
if (s->repo != installed)
@@ -3792,7 +3780,7 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
continue;
supp = s->repo->idarraydata + s->supplements;
while ((sup = *supp++) != 0)
- if (check_xsupp(solv, &iq, sup) && !check_xsupp(solv, 0, sup))
+ if (ISRELDEP(sup) && check_xsupp(solv, &iq, sup) && !check_xsupp(solv, 0, sup))
{
#ifdef CLEANDEPSDEBUG
printf("xsupp %s from %s\n", pool_dep2str(pool, sup), pool_solvid2str(pool, ip));