summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2020-11-27 14:49:41 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2020-11-27 14:49:41 +0900
commit99023ce80ad7daa0f6462861dac71e17aac694b8 (patch)
tree0df34c5c104209ad692e46fe842395cc35436aea /src
parentb712cabb59f7155205489f15a37addb4ac8b0069 (diff)
downloadlibsolv-upstream/0.7.16.tar.gz
libsolv-upstream/0.7.16.tar.bz2
libsolv-upstream/0.7.16.zip
Imported Upstream version 0.7.16upstream/0.7.16
Diffstat (limited to 'src')
-rw-r--r--src/rules.c170
-rw-r--r--src/solver.c8
2 files changed, 110 insertions, 68 deletions
diff --git a/src/rules.c b/src/rules.c
index ffa2988..6c8e82b 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -3187,6 +3187,44 @@ solver_choicerulecheck(Solver *solv, Id pi, Rule *r, Map *m, Queue *q)
return 1; /* none of the new packages provided it */
}
+static int
+solver_choicerulecheck2(Solver *solv, Id pi, Id pt, Queue *q)
+{
+ Pool *pool = solv->pool;
+ Rule *ur;
+ Id p, pp;
+ int i;
+
+ if (!q->count || q->elements[0] != pi)
+ {
+ if (q->count)
+ queue_empty(q);
+ ur = solv->rules + solv->updaterules + (pi - pool->installed->start);
+ if (!ur->p)
+ ur = solv->rules + solv->featurerules + (pi - pool->installed->start);
+ if (!ur->p)
+ return 0;
+ queue_push2(q, pi, 0);
+ FOR_RULELITERALS(p, pp, ur)
+ if (p > 0 && p != pi)
+ queue_push(q, p);
+ queue_push(q, pi);
+ }
+ if (q->count <= 3)
+ return q->count == 3 && q->elements[2] == pt ? 1 : 0;
+ if (!q->elements[1])
+ {
+ queue_deleten(q, 0, 2);
+ policy_filter_unwanted(solv, q, POLICY_MODE_CHOOSE);
+ queue_unshift(q, 1); /* filter mark */
+ queue_unshift(q, pi);
+ }
+ for (i = 2; i < q->count; i++)
+ if (q->elements[i] == pt)
+ return 1;
+ return 0; /* not newest */
+}
+
static inline void
queue_removeelement(Queue *q, Id el)
{
@@ -3203,20 +3241,62 @@ queue_removeelement(Queue *q, Id el)
}
}
+static Id
+choicerule_find_installed(Pool *pool, Id p)
+{
+ Solvable *s = pool->solvables + p;
+ Id p2, pp2;
+
+ if (!s->repo)
+ return 0;
+ if (s->repo == pool->installed)
+ return p;
+ FOR_PROVIDES(p2, pp2, s->name)
+ {
+ Solvable *s2 = pool->solvables + p2;
+ if (s2->repo != pool->installed)
+ continue;
+ if (!pool->implicitobsoleteusesprovides && s->name != s2->name)
+ continue;
+ if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, s2))
+ continue;
+ return p2;
+ }
+ if (s->obsoletes)
+ {
+ Id obs, *obsp = s->repo->idarraydata + s->obsoletes;
+ while ((obs = *obsp++) != 0)
+ {
+ FOR_PROVIDES(p2, pp2, obs)
+ {
+ Solvable *s2 = pool->solvables + p2;
+ if (s2->repo != pool->installed)
+ continue;
+ if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, pool->solvables + p2, obs))
+ continue;
+ if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2))
+ continue;
+ return p2;
+ }
+ }
+ }
+ return 0;
+}
+
void
solver_addchoicerules(Solver *solv)
{
Pool *pool = solv->pool;
Map m, mneg;
Rule *r;
- Queue q, qi, qcheck, infoq;
+ Queue q, qi, qcheck, qcheck2, infoq;
int i, j, rid, havechoice, negcnt;
- Id p, d, pp;
- Id p2, pp2;
- Solvable *s, *s2;
+ Id p, d, pp, p2;
+ Solvable *s;
Id lastaddedp, lastaddedd;
int lastaddedcnt;
unsigned int now;
+ int isnewest = 0;
solv->choicerules = solv->nrules;
if (!pool->installed)
@@ -3229,6 +3309,7 @@ solver_addchoicerules(Solver *solv)
queue_init(&q);
queue_init(&qi);
queue_init(&qcheck);
+ queue_init(&qcheck2);
queue_init(&infoq);
map_init(&m, pool->nsolvables);
map_init(&mneg, pool->nsolvables);
@@ -3260,80 +3341,28 @@ solver_addchoicerules(Solver *solv)
continue;
if (s->repo == pool->installed)
{
+ queue_push2(&qi, p, p);
queue_push(&q, p);
continue;
}
- /* check if this package is "blocked" by a installed package */
- s2 = 0;
- FOR_PROVIDES(p2, pp2, s->name)
- {
- s2 = pool->solvables + p2;
- if (s2->repo != pool->installed)
- continue;
- if (!pool->implicitobsoleteusesprovides && s->name != s2->name)
- continue;
- if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, s2))
- continue;
- break;
- }
+ /* find an installed package p2 that we can update/downgrade to p */
+ p2 = choicerule_find_installed(pool, p);
if (p2)
{
- /* found installed package p2 that we can update to p */
if (MAPTST(&mneg, p))
continue;
- if (policy_is_illegal(solv, s2, s, 0))
- continue;
-#if 0
- if (solver_choicerulecheck(solv, p2, r, &m))
+ if (policy_is_illegal(solv, pool->solvables + p2, s, 0))
continue;
- queue_push(&qi, p2);
-#else
queue_push2(&qi, p2, p);
-#endif
queue_push(&q, p);
continue;
}
- if (s->obsoletes)
- {
- Id obs, *obsp = s->repo->idarraydata + s->obsoletes;
- s2 = 0;
- while ((obs = *obsp++) != 0)
- {
- FOR_PROVIDES(p2, pp2, obs)
- {
- s2 = pool->solvables + p2;
- if (s2->repo != pool->installed)
- continue;
- if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, pool->solvables + p2, obs))
- continue;
- if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2))
- continue;
- break;
- }
- if (p2)
- break;
- }
- if (obs)
- {
- /* found installed package p2 that we can update to p */
- if (MAPTST(&mneg, p))
- continue;
- if (policy_is_illegal(solv, s2, s, 0))
- continue;
-#if 0
- if (solver_choicerulecheck(solv, p2, r, &m))
- continue;
- queue_push(&qi, p2);
-#else
- queue_push2(&qi, p2, p);
-#endif
- queue_push(&q, p);
- continue;
- }
- }
/* package p is independent of the installed ones */
havechoice = 1;
}
+#if 0
+ printf("havechoice: %d qcount %d qicount %d\n", havechoice, q.count, qi.count);
+#endif
if (!havechoice || !q.count || !qi.count)
continue; /* no choice */
@@ -3341,13 +3370,25 @@ solver_addchoicerules(Solver *solv)
if (p > 0)
MAPSET(&m, p);
+ isnewest = 1;
+ FOR_RULELITERALS(p, pp, r)
+ {
+ if (p > 0)
+ break;
+ p2 = choicerule_find_installed(pool, -p);
+ if (p2 && !solver_choicerulecheck2(solv, p2, -p, &qcheck2))
+ {
+ isnewest = 0;
+ break;
+ }
+ }
/* do extra checking */
for (i = j = 0; i < qi.count; i += 2)
{
p2 = qi.elements[i];
if (!p2)
continue;
- if (solver_choicerulecheck(solv, p2, r, &m, &qcheck))
+ if (isnewest && solver_choicerulecheck(solv, p2, r, &m, &qcheck))
{
/* oops, remove element p from q */
queue_removeelement(&q, qi.elements[i + 1]);
@@ -3441,6 +3482,7 @@ solver_addchoicerules(Solver *solv)
queue_free(&q);
queue_free(&qi);
queue_free(&qcheck);
+ queue_free(&qcheck2);
queue_free(&infoq);
map_free(&m);
map_free(&mneg);
diff --git a/src/solver.c b/src/solver.c
index 686a8af..9c02cc7 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -1198,7 +1198,7 @@ createbranch(Solver *solv, int level, Queue *dq, Id p, Id data)
int i;
IF_POOLDEBUG (SOLV_DEBUG_POLICY)
{
- POOL_DEBUG (SOLV_DEBUG_POLICY, "creating a branch:\n");
+ POOL_DEBUG (SOLV_DEBUG_POLICY, "creating a branch [data=%d]:\n", data);
for (i = 0; i < dq->count; i++)
POOL_DEBUG (SOLV_DEBUG_POLICY, " - %s\n", pool_solvid2str(pool, dq->elements[i]));
}
@@ -1218,7 +1218,7 @@ takebranch(Solver *solv, int pos, int end, const char *msg, int disablerules)
#if 0
{
int i;
- printf("branch group level %d [%d-%d] %d %d:\n", solv->branches.elements[end - 1], start, end, solv->branches.elements[end - 4], solv->branches.elements[end - 3]);
+ printf("branch group level %d [%d-%d] %d %d:\n", solv->branches.elements[end - 1], end - solv->branches.elements[end - 2], end, solv->branches.elements[end - 4], solv->branches.elements[end - 3]);
for (i = end - solv->branches.elements[end - 2]; i < end - 4; i++)
printf("%c %c%s\n", i == pos ? 'x' : ' ', solv->branches.elements[i] >= 0 ? ' ' : '-', pool_solvid2str(pool, solv->branches.elements[i] >= 0 ? solv->branches.elements[i] : -solv->branches.elements[i]));
}
@@ -2089,6 +2089,8 @@ add_complex_recommends(Solver *solv, Id rec, Queue *dq, Map *dqmap)
queue_truncate(dq, blkcnt);
break;
}
+ if (solv->decisionmap[p] < 0)
+ continue;
if (dqmap)
{
if (!MAPTST(dqmap, p))
@@ -2096,8 +2098,6 @@ add_complex_recommends(Solver *solv, Id rec, Queue *dq, Map *dqmap)
}
else
{
- if (solv->decisionmap[p] < 0)
- continue;
if (solv->process_orphans && solv->installed && pool->solvables[p].repo == solv->installed && (solv->droporphanedmap_all || (solv->droporphanedmap.size && MAPTST(&solv->droporphanedmap, p - solv->installed->start))))
continue;
}