X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Frules.c;h=248b1cddf0412cbdaefd6671029472d90898212f;hb=2903497e256388eff53b408875c0f2239c3566cb;hp=b941986b7064afe6738582691deb1d0990fb3fad;hpb=fd257fb9c490f4af3fbfb71c4d099fe876be28eb;p=platform%2Fupstream%2Flibsolv.git diff --git a/src/rules.c b/src/rules.c index b941986..248b1cd 100644 --- a/src/rules.c +++ b/src/rules.c @@ -1157,17 +1157,19 @@ finddistupgradepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all) if (!qs->count) { if (allow_all) - return 0; /* orphaned, don't create feature rule */ + return 0; /* orphaned, don't create feature rule */ /* check if this is an orphaned package */ policy_findupdatepackages(solv, s, qs, 1); if (!qs->count) - return 0; /* orphaned, don't create update rule */ + return 0; /* orphaned, don't create update rule */ qs->count = 0; return -SYSTEMSOLVABLE; /* supported but not installable */ } if (allow_all) return s - pool->solvables; /* check if it is ok to keep the installed package */ + if (solv->dupmap.size && MAPTST(&solv->dupmap, s - pool->solvables)) + return s - pool->solvables; for (i = 0; i < qs->count; i++) { Solvable *ns = pool->solvables + qs->elements[i]; @@ -1178,6 +1180,7 @@ finddistupgradepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all) return -SYSTEMSOLVABLE; } +#if 0 /* add packages from the dup repositories to the update candidates * this isn't needed for the global dup mode as all packages are * from dup repos in that case */ @@ -1201,6 +1204,7 @@ addduppackages(Solver *solv, Solvable *s, Queue *qs) } queue_free(&dupqs); } +#endif /*------------------------------------------------------------------- * @@ -1218,18 +1222,15 @@ solver_addupdaterule(Solver *solv, Solvable *s, int allow_all) Id p, d; Queue qs; Id qsbuf[64]; + int isorphaned = 0; queue_init_buffer(&qs, qsbuf, sizeof(qsbuf)/sizeof(*qsbuf)); p = s - pool->solvables; /* find update candidates for 's' */ - if (solv->dupmap_all) + if (solv->dupmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))) p = finddistupgradepackages(solv, s, &qs, allow_all); else - { - policy_findupdatepackages(solv, s, &qs, allow_all); - if (!allow_all && solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p)) - addduppackages(solv, s, &qs); - } + policy_findupdatepackages(solv, s, &qs, allow_all); #ifdef ENABLE_LINKED_PKGS if (solv->instbuddy && solv->instbuddy[s - pool->solvables - solv->installed->start]) @@ -1237,7 +1238,7 @@ solver_addupdaterule(Solver *solv, Solvable *s, int allow_all) const char *name = pool_id2str(pool, s->name); if (strncmp(name, "pattern:", 8) == 0 || strncmp(name, "application:", 12) == 0) { - /* a linked pseudo package. As it is linked, we do not need an update rule */ + /* a linked pseudo package. As it is linked, we do not need an update/feature rule */ /* nevertheless we set specialupdaters so we can update */ solver_addrule(solv, 0, 0, 0); if (!allow_all && qs.count) @@ -1254,11 +1255,14 @@ solver_addupdaterule(Solver *solv, Solvable *s, int allow_all) } #endif - if (!allow_all && !p && solv->dupmap_all) + if (!allow_all && !p) /* !p implies qs.count == 0 */ { queue_push(&solv->orphaned, s - pool->solvables); /* an orphaned package */ if (solv->keep_orphans && !(solv->droporphanedmap_all || (solv->droporphanedmap.size && MAPTST(&solv->droporphanedmap, s - pool->solvables - solv->installed->start)))) p = s - pool->solvables; /* keep this orphaned package installed */ + queue_free(&qs); + solver_addrule(solv, p, 0, 0); + return; } if (!allow_all && qs.count && solv->multiversion.size) @@ -1271,7 +1275,7 @@ solver_addupdaterule(Solver *solv, Solvable *s, int allow_all) if (i < qs.count) { /* filter out all multiversion packages as they don't update */ - d = pool_queuetowhatprovides(pool, &qs); + d = pool_queuetowhatprovides(pool, &qs); /* save qs away */ for (j = i; i < qs.count; i++) { if (MAPTST(&solv->multiversion, qs.elements[i])) @@ -1290,19 +1294,25 @@ solver_addupdaterule(Solver *solv, Solvable *s, int allow_all) } qs.elements[j++] = qs.elements[i]; } - if (j < qs.count) + if (j < qs.count) /* filtered at least one package? */ { - if (d && solv->installed && s->repo == solv->installed && - (solv->updatemap_all || (solv->updatemap.size && MAPTST(&solv->updatemap, s - pool->solvables - solv->installed->start)))) + if (j == 0 && p == -SYSTEMSOLVABLE) { + /* this is a multiversion orphan */ + queue_push(&solv->orphaned, s - pool->solvables); if (!solv->specialupdaters) solv->specialupdaters = solv_calloc(solv->installed->end - solv->installed->start, sizeof(Id)); solv->specialupdaters[s - pool->solvables - solv->installed->start] = d; - } - if (j == 0 && p == -SYSTEMSOLVABLE && solv->dupmap_all) - { - queue_push(&solv->orphaned, s - pool->solvables); /* also treat as orphaned */ - j = qs.count; + if (solv->keep_orphans && !(solv->droporphanedmap_all || (solv->droporphanedmap.size && MAPTST(&solv->droporphanedmap, s - pool->solvables - solv->installed->start)))) + { + /* we need to keep the orphan */ + queue_free(&qs); + solver_addrule(solv, s - pool->solvables, 0, 0); + return; + } + /* we can drop it as long as we update */ + isorphaned = 1; + j = qs.count; /* force the update */ } qs.count = j; } @@ -1310,11 +1320,13 @@ 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, 0, d); /* allow update of s */ + solver_addrule(solv, s - pool->solvables, 0, d); /* allow update of s */ return; } } } + if (!isorphaned && p == -SYSTEMSOLVABLE && solv->dupmap.size) + p = s - pool->solvables; /* let the dup rules sort it out */ if (qs.count && p == -SYSTEMSOLVABLE) p = queue_shift(&qs); if (qs.count > 1) @@ -1623,7 +1635,7 @@ add_cleandeps_package(Solver *solv, Id p) queue_pushunique(solv->cleandeps_updatepkgs, p); } -static inline void +static void solver_addtodupmaps(Solver *solv, Id p, Id how, int targeted) { Pool *pool = solv->pool; @@ -1796,9 +1808,11 @@ void solver_addduprules(Solver *solv, Map *addedmap) { Pool *pool = solv->pool; + Repo *installed = solv->installed; Id p, pp; Solvable *s, *ps; int first, i; + Rule *r; solv->duprules = solv->nrules; for (i = 1; i < pool->nsolvables; i++) @@ -1818,11 +1832,11 @@ solver_addduprules(Solver *solv, Map *addedmap) break; if (!MAPTST(&solv->dupinvolvedmap, p)) continue; - if (solv->installed && ps->repo == solv->installed) + if (installed && ps->repo == installed) { if (!solv->updatemap.size) - map_grow(&solv->updatemap, solv->installed->end - solv->installed->start); - MAPSET(&solv->updatemap, p - solv->installed->start); + map_grow(&solv->updatemap, installed->end - installed->start); + MAPSET(&solv->updatemap, p - installed->start); if (!MAPTST(&solv->dupmap, p)) { Id ip, ipp; @@ -1835,10 +1849,22 @@ solver_addduprules(Solver *solv, Map *addedmap) if (is->evr == ps->evr && solvable_identical(ps, is)) break; } - if (!ip) - solver_addrule(solv, -p, 0, 0); /* no match, sorry */ - else - MAPSET(&solv->dupmap, p); /* for best rules processing */ + if (ip) + { + /* ok, found a good one. we may keep this package. */ + MAPSET(&solv->dupmap, p); /* for best rules processing */ + continue; + } + r = solv->rules + solv->updaterules + (p - installed->start); + if (!r->p) + r = solv->rules + solv->featurerules + (p - installed->start); + if (r->p && solv->specialupdaters && solv->specialupdaters[p - installed->start]) + { + /* this is a multiversion orphan, we're good if an update is installed */ + solver_addrule(solv, -p, 0, solv->specialupdaters[p - installed->start]); + continue; + } + solver_addrule(solv, -p, 0, 0); /* no match, sorry */ } } else if (!MAPTST(&solv->dupmap, p)) @@ -2823,32 +2849,51 @@ solver_rule2rules(Solver *solv, Id rid, Queue *q, int recursive) /* check if the newest versions of pi still provides the dependency we're looking for */ static int -solver_choicerulecheck(Solver *solv, Id pi, Rule *r, Map *m) +solver_choicerulecheck(Solver *solv, Id pi, Rule *r, Map *m, Queue *q) { Pool *pool = solv->pool; Rule *ur; - Queue q; - Id p, pp, qbuf[32]; + Id p, pp; int i; - 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_init_buffer(&q, qbuf, sizeof(qbuf)/sizeof(*qbuf)); - FOR_RULELITERALS(p, pp, ur) - if (p > 0) - queue_push(&q, p); - if (q.count > 1) - policy_filter_unwanted(solv, &q, POLICY_MODE_CHOOSE); - for (i = 0; i < q.count; i++) - if (MAPTST(m, q.elements[i])) - break; - /* 1: none of the newest versions provide it */ - i = i == q.count ? 1 : 0; - queue_free(&q); - return 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) + queue_push(q, p); + } + if (q->count == 2) + return 1; + if (q->count == 3) + { + p = q->elements[2]; + return MAPTST(m, p) ? 0 : 1; + } + if (!q->elements[1]) + { + for (i = 2; i < q->count; i++) + if (!MAPTST(m, q->elements[i])) + break; + if (i == q->count) + return 0; /* all provide it, no need to filter */ + /* some don't provide it, have to filter */ + 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 (MAPTST(m, q->elements[i])) + return 0; /* at least one provides it */ + return 1; /* none of the new packages provided it */ } static inline void @@ -2873,7 +2918,7 @@ solver_addchoicerules(Solver *solv) Pool *pool = solv->pool; Map m, mneg; Rule *r; - Queue q, qi; + Queue q, qi, qcheck; int i, j, rid, havechoice; Id p, d, pp; Id p2, pp2; @@ -2892,6 +2937,7 @@ solver_addchoicerules(Solver *solv) solv->choicerules_ref = solv_calloc(solv->pkgrules_end, sizeof(Id)); queue_init(&q); queue_init(&qi); + queue_init(&qcheck); map_init(&m, pool->nsolvables); map_init(&mneg, pool->nsolvables); /* set up negative assertion map from infarch and dup rules */ @@ -3009,7 +3055,7 @@ solver_addchoicerules(Solver *solv) p2 = qi.elements[i]; if (!p2) continue; - if (solver_choicerulecheck(solv, p2, r, &m)) + if (solver_choicerulecheck(solv, p2, r, &m, &qcheck)) { /* oops, remove element p from q */ queue_removeelement(&q, qi.elements[i + 1]); @@ -3018,6 +3064,7 @@ solver_addchoicerules(Solver *solv) qi.elements[j++] = p2; } queue_truncate(&qi, j); + if (!q.count || !qi.count) { FOR_RULELITERALS(p, pp, r) @@ -3089,6 +3136,7 @@ solver_addchoicerules(Solver *solv) } queue_free(&q); queue_free(&qi); + queue_free(&qcheck); map_free(&m); map_free(&mneg); solv->choicerules_end = solv->nrules;