From: Michael Schroeder Date: Mon, 17 Nov 2008 14:40:37 +0000 (+0000) Subject: - fix old FIXME by not pruning installed packages X-Git-Tag: BASE-SuSE-Code-12_1-Branch~378 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c227734f7e0ae59e888071b07e280afd891fafda;p=platform%2Fupstream%2Flibsolv.git - fix old FIXME by not pruning installed packages - add repo sub-priority, used for comparing and not pruning useful for prefering some source url --- diff --git a/src/policy.c b/src/policy.c index ab3dd46..37d2134 100644 --- a/src/policy.c +++ b/src/policy.c @@ -22,7 +22,7 @@ #include "poolarch.h" -static Solver *prune_best_version_arch_sortcmp_data; +static Solver *prune_to_best_version_sortcmp_data; /*-----------------------------------------------------------------*/ @@ -32,21 +32,25 @@ static Solver *prune_best_version_arch_sortcmp_data; */ static int -prune_best_version_arch_sortcmp(const void *ap, const void *bp) +prune_to_best_version_sortcmp(const void *ap, const void *bp) { - Solver *solv = prune_best_version_arch_sortcmp_data; + Solver *solv = prune_to_best_version_sortcmp_data; Pool *pool = solv->pool; int r; Id a = *(Id *)ap; Id b = *(Id *)bp; - r = pool->solvables[a].name - pool->solvables[b].name; + Solvable *sa, *sb; + + sa = pool->solvables + a; + sb = pool->solvables + b; + r = sa->name - sb->name; if (r) { const char *na, *nb; /* different names. We use real strcmp here so that the result * is not depending on some random solvable order */ - na = id2str(pool, pool->solvables[a].name); - nb = id2str(pool, pool->solvables[b].name); + na = id2str(pool, sa->name); + nb = id2str(pool, sb->name); /* bring patterns to the front */ /* XXX: no longer needed? */ if (!strncmp(na, "pattern:", 8)) @@ -61,22 +65,29 @@ prune_best_version_arch_sortcmp(const void *ap, const void *bp) } return strcmp(na, nb); } - /* the same name */ - if (pool->solvables[a].evr == pool->solvables[b].evr && solv->installed) + /* the same name, bring installed solvables to the front */ + if (solv->installed) { - /* prefer installed solvables */ - if (pool->solvables[a].repo == solv->installed) - return -1; - if (pool->solvables[b].repo == solv->installed) + if (sa->repo == solv->installed) + { + if (sb->repo != solv->installed) + return -1; + } + else if (sb->repo == solv->installed) return 1; } + /* sort by repository sub-prio (installed repo handled above) */ + r = (sb->repo ? sb->repo->subpriority : 0) - (sa->repo ? sa->repo->subpriority : 0); + if (r) + return r; + /* no idea about the order, sort by id */ return a - b; } /* - * prune to repository with highest priority - * + * prune to repository with highest priority. + * does not prune installed solvables. */ static void @@ -90,13 +101,15 @@ prune_to_highest_prio(Pool *pool, Queue *plist) for (i = 0; i < plist->count; i++) /* find highest prio in queue */ { s = pool->solvables + plist->elements[i]; + if (pool->installed && s->repo == pool->installed) + continue; if (i == 0 || s->repo->priority > bestprio) bestprio = s->repo->priority; } for (i = j = 0; i < plist->count; i++) /* remove all with lower prio */ { s = pool->solvables + plist->elements[i]; - if (s->repo->priority == bestprio) + if (s->repo->priority == bestprio || (pool->installed && s->repo == pool->installed)) plist->elements[j++] = plist->elements[i]; } plist->count = j; @@ -104,20 +117,33 @@ prune_to_highest_prio(Pool *pool, Queue *plist) /* - * prune_to_recommended - * - * XXX: should we prune to requires/suggests that are already - * fulfilled by other packages? + * prune to recommended/suggested packages. + * does not prune installed packages (they are also somewhat recommended). */ static void prune_to_recommended(Solver *solv, Queue *plist) { Pool *pool = solv->pool; - int i, j; + int i, j, k, ninst; Solvable *s; Id p, pp, rec, *recp, sug, *sugp; + ninst = 0; + if (pool->installed) + { + for (i = 0; i < plist->count; i++) + { + p = plist->elements[i]; + s = pool->solvables + p; + if (pool->installed && s->repo == pool->installed) + ninst++; + } + } + if (plist->count - ninst < 2) + return; + + /* update our recommendsmap/suggestsmap */ if (solv->recommends_index < 0) { MAPZERO(&solv->recommendsmap); @@ -145,34 +171,67 @@ prune_to_recommended(Solver *solv, Queue *plist) MAPSET(&solv->suggestsmap, p); } } + /* prune to recommended/supplemented */ + ninst = 0; for (i = j = 0; i < plist->count; i++) { p = plist->elements[i]; - if (MAPTST(&solv->recommendsmap, p)) + s = pool->solvables + p; + if (pool->installed && s->repo == pool->installed) { - plist->elements[j++] = p; + ninst++; + if (j) + plist->elements[j++] = p; continue; } - if (solver_is_supplementing(solv, pool->solvables + p)) - plist->elements[j++] = p; + if (!MAPTST(&solv->recommendsmap, p)) + if (!solver_is_supplementing(solv, s)) + continue; + if (!j && ninst) + { + for (k = 0; j < ninst; k++) + { + s = pool->solvables + plist->elements[k]; + if (pool->installed && s->repo == pool->installed) + plist->elements[j++] = plist->elements[k]; + } + } + plist->elements[j++] = p; } if (j) plist->count = j; - /* prune to suggested/enhanced*/ - if (plist->count < 2) + /* anything left to prune? */ + if (plist->count - ninst < 2) return; + + /* prune to suggested/enhanced*/ + ninst = 0; for (i = j = 0; i < plist->count; i++) { p = plist->elements[i]; - if (MAPTST(&solv->suggestsmap, p)) + s = pool->solvables + p; + if (pool->installed && s->repo == pool->installed) { - plist->elements[j++] = p; + ninst++; + if (j) + plist->elements[j++] = p; continue; } - if (solver_is_enhancing(solv, pool->solvables + p)) - plist->elements[j++] = p; + if (!MAPTST(&solv->suggestsmap, p)) + if (!solver_is_enhancing(solv, s)) + continue; + if (!j && ninst) + { + for (k = 0; j < ninst; k++) + { + s = pool->solvables + plist->elements[k]; + if (pool->installed && s->repo == pool->installed) + plist->elements[j++] = plist->elements[k]; + } + } + plist->elements[j++] = p; } if (j) plist->count = j; @@ -217,14 +276,12 @@ prune_to_best_arch(Pool *pool, Queue *plist) * * sort list of packages (given through plist) by name and evr * return result through plist - * */ - void prune_to_best_version(Solver *solv, Queue *plist) { Pool *pool = solv->pool; - Id best = ID_NULL; + Id best; int i, j; Solvable *s; @@ -232,9 +289,9 @@ prune_to_best_version(Solver *solv, Queue *plist) return; POOL_DEBUG(SAT_DEBUG_POLICY, "prune_to_best_version %d\n", plist->count); - prune_best_version_arch_sortcmp_data = solv; + prune_to_best_version_sortcmp_data = solv; /* sort by name first, prefer installed */ - qsort(plist->elements, plist->count, sizeof(Id), prune_best_version_arch_sortcmp); + qsort(plist->elements, plist->count, sizeof(Id), prune_to_best_version_sortcmp); /* delete obsoleted. hmm, looks expensive! */ /* FIXME maybe also check provides depending on noupdateprovide? */ @@ -264,12 +321,14 @@ prune_to_best_version(Solver *solv, Queue *plist) } } } + /* delete zeroed out queue entries */ for (i = j = 0; i < plist->count; i++) if (plist->elements[i]) plist->elements[j++] = plist->elements[i]; plist->count = j; /* now find best 'per name' */ + best = 0; for (i = j = 0; i < plist->count; i++) { s = pool->solvables + plist->elements[i]; @@ -327,17 +386,13 @@ prune_best_arch_name_version(Solver *solv, Pool *pool, Queue *plist) void -policy_filter_unwanted(Solver *solv, Queue *plist, Id inst, int mode) +policy_filter_unwanted(Solver *solv, Queue *plist, int mode) { Pool *pool = solv->pool; if (plist->count > 1 && mode != POLICY_MODE_SUGGEST) prune_to_highest_prio(pool, plist); if (plist->count > 1 && mode == POLICY_MODE_CHOOSE) prune_to_recommended(solv, plist); - /* FIXME: do this different! */ - if (inst) - queue_push(plist, inst); - prune_best_arch_name_version(solv, pool, plist); } diff --git a/src/policy.h b/src/policy.h index 9050a3e..5574572 100644 --- a/src/policy.h +++ b/src/policy.h @@ -55,7 +55,7 @@ extern void prune_to_best_version(Solver *solv, Queue *plist); * candidates : List of candidates (This list depends on other * restrictions like architecture and vendor policies too) */ -extern void policy_filter_unwanted(Solver *solv, Queue *plist, Id inst, int mode); +extern void policy_filter_unwanted(Solver *solv, Queue *plist, int mode); extern int policy_illegal_archchange(Solver *solv, Solvable *s1, Solvable *s2); extern int policy_illegal_vendorchange(Solver *solv, Solvable *s1, Solvable *s2); extern void policy_findupdatepackages(Solver *solv, diff --git a/src/repo.h b/src/repo.h index 7f81d27..8c097ef 100644 --- a/src/repo.h +++ b/src/repo.h @@ -28,6 +28,7 @@ typedef struct _Repo { int nsolvables; /* number of solvables repo is contributing to pool */ int priority; /* priority of this repo */ + int subpriority; /* sub-priority of this repo, used just for sorting, not pruning */ Id *idarraydata; /* array of metadata Ids, solvable dependencies are offsets into this array */ int idarraysize; diff --git a/src/solver.c b/src/solver.c index 175cd18..6747c10 100644 --- a/src/solver.c +++ b/src/solver.c @@ -2308,42 +2308,36 @@ setpropagatelearn(Solver *solv, int level, Id decision, int disablerules) */ static int -selectandinstall(Solver *solv, int level, Queue *dq, Id inst, int disablerules) +selectandinstall(Solver *solv, int level, Queue *dq, int disablerules) { Pool *pool = solv->pool; Id p; int i; - /* FIXME: do we really need that inst handling? */ - if (solv->distupgrade && inst && dq->count) - { - policy_filter_unwanted(solv, dq, 0, POLICY_MODE_CHOOSE); - for (i = 0; i < dq->count; i++) - if (solvable_identical(pool, pool->solvables + inst, pool->solvables + dq->elements[i])) - dq->elements[i] = inst; - } - else - { - if (dq->count > 1 || inst) - policy_filter_unwanted(solv, dq, inst, POLICY_MODE_CHOOSE); - } - - i = 0; + if (dq->count > 1) + policy_filter_unwanted(solv, dq, POLICY_MODE_CHOOSE); if (dq->count > 1) { + /* XXX: didn't we already do that? */ + /* XXX: shouldn't we prefer installed packages? */ + /* XXX: move to policy.c? */ /* choose the supplemented one */ for (i = 0; i < dq->count; i++) if (solver_is_supplementing(solv, pool->solvables + dq->elements[i])) - break; - if (i == dq->count) - { - for (i = 1; i < dq->count; i++) - queue_push(&solv->branches, dq->elements[i]); - queue_push(&solv->branches, -level); - i = 0; - } + { + dq->elements[0] = dq->elements[i]; + dq->count = 1; + break; + } + } + if (dq->count > 1) + { + /* multiple candidates, open a branch */ + for (i = 1; i < dq->count; i++) + queue_push(&solv->branches, dq->elements[i]); + queue_push(&solv->branches, -level); } - p = dq->elements[i]; + p = dq->elements[0]; POOL_DEBUG(SAT_DEBUG_POLICY, "installing %s\n", solvable2str(pool, pool->solvables + p)); @@ -2553,7 +2547,7 @@ run_solver(Solver *solv, int disablerules, int doweak) dq.count = k; } olevel = level; - level = selectandinstall(solv, level, &dq, 0, disablerules); + level = selectandinstall(solv, level, &dq, disablerules); if (level == 0) { queue_free(&dq); @@ -2628,10 +2622,11 @@ run_solver(Solver *solv, int disablerules, int doweak) if (!d) continue; queue_empty(&dq); + queue_push(&dq, i); while ((p = pool->whatprovidesdata[d++]) != 0) if (solv->decisionmap[p] >= 0) queue_push(&dq, p); - policy_filter_unwanted(solv, &dq, i, POLICY_MODE_CHOOSE); + policy_filter_unwanted(solv, &dq, POLICY_MODE_CHOOSE); p = dq.elements[0]; if (p != i && solv->decisionmap[p] == 0) { @@ -2680,7 +2675,6 @@ run_solver(Solver *solv, int disablerules, int doweak) for (i = solv->installed->start, r = solv->rules + solv->updaterules; i < solv->installed->end; i++, r++) { Rule *rr; - Id inst; s = pool->solvables + i; /* skip if not installed (can't update) */ @@ -2713,16 +2707,8 @@ run_solver(Solver *solv, int disablerules, int doweak) } if (p || !dq.count) /* already fulfilled or empty */ continue; - if (dq.elements[0] == i) - inst = queue_shift(&dq); - else - inst = 0; olevel = level; - /* FIXME: it is handled a bit different because we do not want - * to have it pruned just because it is not recommened. - * we should not prune installed packages instead. - */ - level = selectandinstall(solv, level, &dq, inst, disablerules); + level = selectandinstall(solv, level, &dq, disablerules); if (level == 0) { queue_free(&dq); @@ -2815,7 +2801,7 @@ run_solver(Solver *solv, int disablerules, int doweak) assert(dq.count > 1); olevel = level; - level = selectandinstall(solv, level, &dq, 0, disablerules); + level = selectandinstall(solv, level, &dq, disablerules); if (level == 0) { queue_free(&dq); @@ -2921,7 +2907,7 @@ run_solver(Solver *solv, int disablerules, int doweak) if (dq.count) { if (dq.count > 1) - policy_filter_unwanted(solv, &dq, 0, POLICY_MODE_RECOMMEND); + policy_filter_unwanted(solv, &dq, POLICY_MODE_RECOMMEND); p = dq.elements[0]; POOL_DEBUG(SAT_DEBUG_POLICY, "installing recommended %s\n", solvable2str(pool, pool->solvables + p)); queue_push(&solv->recommendations, p); @@ -4588,7 +4574,7 @@ solver_solve(Solver *solv, Queue *job) queue_pushunique(&solv->recommendations, i); } /* we use MODE_SUGGEST here so that repo prio is ignored */ - policy_filter_unwanted(solv, &solv->recommendations, 0, POLICY_MODE_SUGGEST); + policy_filter_unwanted(solv, &solv->recommendations, POLICY_MODE_SUGGEST); } /* @@ -4649,7 +4635,7 @@ solver_solve(Solver *solv, Queue *job) } queue_push(&solv->suggestions, i); } - policy_filter_unwanted(solv, &solv->suggestions, 0, POLICY_MODE_SUGGEST); + policy_filter_unwanted(solv, &solv->suggestions, POLICY_MODE_SUGGEST); } if (redoq.count)