diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libsolv.ver | 2 | ||||
-rw-r--r-- | src/policy.c | 202 | ||||
-rw-r--r-- | src/policy.h | 2 | ||||
-rw-r--r-- | src/pool.c | 47 | ||||
-rw-r--r-- | src/pool.h | 1 | ||||
-rw-r--r-- | src/poolarch.c | 25 | ||||
-rw-r--r-- | src/selection.c | 93 | ||||
-rw-r--r-- | src/selection.h | 2 | ||||
-rw-r--r-- | src/solver.c | 130 | ||||
-rw-r--r-- | src/solver.h | 7 |
10 files changed, 472 insertions, 39 deletions
diff --git a/src/libsolv.ver b/src/libsolv.ver index cc79704..a5efd6a 100644 --- a/src/libsolv.ver +++ b/src/libsolv.ver @@ -120,6 +120,7 @@ SOLV_1.0 { pool_trivial_installable_multiversionmap; pool_vendor2mask; pool_whatmatchesdep; + pool_whatcontainsdep; queue_alloc_one; queue_alloc_one_head; queue_delete; @@ -245,6 +246,7 @@ SOLV_1.0 { selection_add; selection_filter; selection_make; + selection_make_matchdepid; selection_make_matchdeps; selection_solvables; solv_bin2hex; diff --git a/src/policy.c b/src/policy.c index 12ad771..3a0a737 100644 --- a/src/policy.c +++ b/src/policy.c @@ -453,6 +453,89 @@ prefer_suggested(Solver *solv, Queue *plist) } } +static int +sort_by_favorq_cmp(const void *ap, const void *bp, void *dp) +{ + const Id *a = ap, *b = bp, *d = dp; + return d[b[0]] - d[a[0]]; +} + +static void +sort_by_favorq(Queue *favorq, Id *el, int cnt) +{ + int i; + /* map to offsets into favorq */ + for (i = 0; i < cnt; i++) + { + Id p = el[i]; + /* lookup p in sorted favorq */ + int med = 0, low = 0; + int high = favorq->count / 2; + while (low != high) + { + med = (low + high) / 2; + Id pp = favorq->elements[2 * med]; + if (pp < p) + low = med; + else if (pp > p) + high = med; + else + break; + } + while(med && favorq->elements[2 * med - 2] == p) + med--; + if (favorq->elements[2 * med] == p) + el[i] = 2 * med + 1; + else + el[i] = 0; /* hmm */ + } + /* sort by position */ + solv_sort(el, cnt, sizeof(Id), sort_by_favorq_cmp, favorq->elements); + /* map back */ + for (i = 0; i < cnt; i++) + if (el[i]) + el[i] = favorq->elements[el[i] - 1]; +} + +/* bring favored packages to front and disfavored packages to back */ +void +policy_prefer_favored(Solver *solv, Queue *plist) +{ + int i, fav, disfav, count; + if (!solv->favormap.size) + return; + for (i = fav = disfav = 0, count = plist->count; i < count; i++) + { + Id p = plist->elements[i]; + if (!MAPTST(&solv->favormap, p)) + continue; + if (solv->isdisfavormap.size && MAPTST(&solv->isdisfavormap, p)) + { + /* disfavored package. bring to back */ + if (i < plist->count - 1) + { + memmove(plist->elements + i, plist->elements + i + 1, (plist->count - 1 - i) * sizeof(Id)); + plist->elements[plist->count - 1] = p; + } + i--; + count--; + disfav++; + } + else + { + /* favored package. bring to front */ + if (i > fav) + memmove(plist->elements + fav + 1, plist->elements + fav, (i - fav) * sizeof(Id)); + plist->elements[fav++] = p; + } + } + /* if we have multiple favored/disfavored packages, sort by favorq index */ + if (fav > 1) + sort_by_favorq(solv->favorq, plist->elements, fav); + if (disfav > 1) + sort_by_favorq(solv->favorq, plist->elements + plist->count - disfav, disfav); +} + /* * prune to recommended/suggested packages. * does not prune installed packages (they are also somewhat recommended). @@ -1112,6 +1195,111 @@ dislike_old_versions(Pool *pool, Queue *plist) } } + +/* special lang package handling for urpm */ +/* see https://bugs.mageia.org/show_bug.cgi?id=18315 */ + +static int +urpm_reorder_cmp(const void *ap, const void *bp, void *dp) +{ + return ((Id *)bp)[1] - ((Id *)ap)[1]; +} + +static void +urpm_reorder(Solver *solv, Queue *plist) +{ + Pool *pool = solv->pool; + int i, count = plist->count; + /* add locale score to packages */ + queue_insertn(plist, count, count, 0); + for (i = count - 1; i >= 0; i--) + { + Solvable *s = pool->solvables + plist->elements[i]; + int score = 1; + const char *sn = pool_id2str(pool, s->name); + + if (!strncmp(sn, "kernel-", 7)) + { + const char *devel = strstr(sn, "-devel-"); + if (devel && strlen(sn) < 256) + { + char kn[256]; + Id p, pp, knid; + memcpy(kn, sn, devel - sn); + strcpy(kn + (devel - sn), devel + 6); + knid = pool_str2id(pool, kn, 0); + if (knid) + { + FOR_PROVIDES(p, pp, knid) + if (solv->decisionmap[p] > 0 || (pool->installed && pool->solvables[p].repo == pool->installed)) + score = 3; + } + } + } + else if ((sn = strstr(sn, "-kernel-")) != 0) + { + sn += 8; + if (strlen(sn) < 256 - 8 && *sn >= '0' && *sn <= '9' && sn[1] == '.') + { + const char *flavor = strchr(sn, '-'); + if (flavor) + { + const char *release = strchr(flavor + 1, '-'); + if (release) + { + char kn[256]; + Id p, pp, knid; + memcpy(kn, "kernel", 8); + memcpy(kn + 6, flavor, release - flavor + 1); + memcpy(kn + 6 + (release - flavor) + 1, sn, flavor - sn); + strcpy(kn + 6 + (release + 1 - sn), release); + knid = pool_str2id(pool, kn, 0); + if (knid) + { + FOR_PROVIDES(p, pp, knid) + if (solv->decisionmap[p] > 0 || (pool->installed && pool->solvables[p].repo == pool->installed)) + score = 3; + } + } + } + } + } + if (score == 1 && s->requires) + { + Id id, *idp, p, pp; + const char *deps; + for (idp = s->repo->idarraydata + s->requires; (id = *idp) != 0; idp++) + { + while (ISRELDEP(id)) + { + Reldep *rd = GETRELDEP(pool, id); + id = rd->name; + } + deps = strstr(pool_id2str(pool, id), "locales-"); + if (!deps) + continue; + if (!strncmp(deps + 8, "en", 2)) + score = 2; + else + { + score = 0; + FOR_PROVIDES(p, pp, id) + if (solv->decisionmap[p] > 0 || (pool->installed && pool->solvables[p].repo == pool->installed)) + score = 3; + break; + } + } + } + plist->elements[i * 2] = plist->elements[i]; + plist->elements[i * 2 + 1] = score; + } + solv_sort(plist->elements, count, sizeof(Id) * 2, urpm_reorder_cmp, pool); + for (i = 0; i < count; i++) + plist->elements[i] = plist->elements[2 * i]; + queue_truncate(plist, count); +} + + /* * POLICY_MODE_CHOOSE: default, do all pruning steps * POLICY_MODE_RECOMMEND: leave out prune_to_recommended @@ -1121,6 +1309,17 @@ void policy_filter_unwanted(Solver *solv, Queue *plist, int mode) { Pool *pool = solv->pool; + if (mode == POLICY_MODE_SUPPLEMENT) + { + /* reorder only */ + dislike_old_versions(pool, plist); + sort_by_common_dep(pool, plist); + if (solv->urpmreorder) + urpm_reorder(solv, plist); + prefer_suggested(solv, plist); + policy_prefer_favored(solv, plist); + return; + } if (plist->count > 1) { if (mode != POLICY_MODE_SUGGEST) @@ -1143,7 +1342,10 @@ policy_filter_unwanted(Solver *solv, Queue *plist, int mode) #endif dislike_old_versions(pool, plist); sort_by_common_dep(pool, plist); + if (solv->urpmreorder) + urpm_reorder(solv, plist); prefer_suggested(solv, plist); + policy_prefer_favored(solv, plist); } } } diff --git a/src/policy.h b/src/policy.h index 73410ee..0c3c7cb 100644 --- a/src/policy.h +++ b/src/policy.h @@ -20,6 +20,7 @@ extern "C" { #define POLICY_MODE_RECOMMEND 1 #define POLICY_MODE_SUGGEST 2 #define POLICY_MODE_CHOOSE_NOREORDER 3 /* internal, do not use */ +#define POLICY_MODE_SUPPLEMENT 4 /* internal, do not use */ #define POLICY_ILLEGAL_DOWNGRADE 1 @@ -39,6 +40,7 @@ extern void policy_create_obsolete_index(Solver *solv); /* internal, do not use */ extern void prune_to_best_version(Pool *pool, Queue *plist); +extern void policy_prefer_favored(Solver *solv, Queue *plist); #ifdef __cplusplus @@ -1331,8 +1331,11 @@ void pool_whatmatchesdep(Pool *pool, Id keyname, Id dep, Queue *q, int marker) { Id p; + Queue qq; + int i; queue_empty(q); + queue_init(&qq); FOR_POOL_SOLVABLES(p) { Solvable *s = pool->solvables + p; @@ -1340,9 +1343,49 @@ pool_whatmatchesdep(Pool *pool, Id keyname, Id dep, Queue *q, int marker) continue; if (s->repo != pool->installed && !pool_installable(pool, s)) continue; - if (solvable_matchesdep(s, keyname, dep, marker)) - queue_push(q, p); + if (qq.count) + queue_empty(&qq); + solvable_lookup_deparray(s, keyname, &qq, marker); + for (i = 0; i < qq.count; i++) + if (pool_match_dep(pool, qq.elements[i], dep)) + { + queue_push(q, p); + break; + } + } + queue_free(&qq); +} + +/* check if keyname contains dep, return list of matching packages */ +void +pool_whatcontainsdep(Pool *pool, Id keyname, Id dep, Queue *q, int marker) +{ + Id p; + Queue qq; + int i; + + queue_empty(q); + if (!dep) + return; + queue_init(&qq); + FOR_POOL_SOLVABLES(p) + { + Solvable *s = pool->solvables + p; + if (s->repo->disabled) + continue; + if (s->repo != pool->installed && !pool_installable(pool, s)) + continue; + if (qq.count) + queue_empty(&qq); + solvable_lookup_deparray(s, keyname, &qq, marker); + for (i = 0; i < qq.count; i++) + if (qq.elements[i] == dep) + { + queue_push(q, p); + break; + } } + queue_free(&qq); } /*************************************************************************/ @@ -347,6 +347,7 @@ static inline Id *pool_whatprovides_ptr(Pool *pool, Id d) } void pool_whatmatchesdep(Pool *pool, Id keyname, Id dep, Queue *q, int marker); +void pool_whatcontainsdep(Pool *pool, Id keyname, Id dep, Queue *q, int marker); /* search the pool. the following filters are available: * p - search just this solvable diff --git a/src/poolarch.c b/src/poolarch.c index 788646b..83cbd62 100644 --- a/src/poolarch.c +++ b/src/poolarch.c @@ -29,16 +29,10 @@ static const char *archpolicies[] = { "i686", "i686:i586:i486:i386", "i586", "i586:i486:i386", "i486", "i486:i386", - "i386", "i386", "s390x", "s390x:s390", - "s390", "s390", - "ppc64le", "ppc64le", "ppc64", "ppc64:ppc", - "ppc", "ppc", "ppc64p7", "ppc64p7:ppc64:ppc", "ia64", "ia64:i686:i586:i486:i386", - "aarch64", "aarch64", - "armv6hl", "armv6hl", "armv7hnl", "armv7hnl:armv7hl:armv6hl", "armv7hl", "armv7hl:armv6hl", "armv7l", "armv7l:armv6l:armv5tejl:armv5tel:armv5l:armv4tl:armv4l:armv3l", @@ -49,21 +43,12 @@ static const char *archpolicies[] = { "armv5l", "armv5l:armv4tl:armv4l:armv3l", "armv4tl", "armv4tl:armv4l:armv3l", "armv4l", "armv4l:armv3l", - "armv3l", "armv3l", - "sh3", "sh3", - "sh4", "sh4", "sh4a", "sh4a:sh4", "sparc64v", "sparc64v:sparc64:sparcv9v:sparcv9:sparcv8:sparc", "sparc64", "sparc64:sparcv9:sparcv8:sparc", "sparcv9v", "sparcv9v:sparcv9:sparcv8:sparc", "sparcv9", "sparcv9:sparcv8:sparc", "sparcv8", "sparcv8:sparc", - "sparc", "sparc", - "mips", "mips", - "mipsel", "mipsel", - "mips64", "mips64", - "mips64el", "mips64el", - "m68k", "m68k", #if defined(FEDORA) || defined(MAGEIA) "ia32e", "ia32e:x86_64:athlon:i686:i586:i486:i386", "athlon", "athlon:i686:i586:i486:i386", @@ -81,15 +66,13 @@ pool_setarch(Pool *pool, const char *arch) if (arch) { int i; - /* convert arch to known policy */ for (i = 0; archpolicies[i]; i += 2) if (!strcmp(archpolicies[i], arch)) - break; - if (archpolicies[i]) - arch = archpolicies[i + 1]; - else - arch = ""; + { + arch = archpolicies[i + 1]; + break; + } } pool_setarchpolicy(pool, arch); } diff --git a/src/selection.c b/src/selection.c index 7d9a918..6b89ab0 100644 --- a/src/selection.c +++ b/src/selection.c @@ -867,6 +867,19 @@ selection_make(Pool *pool, Queue *selection, const char *name, int flags) return ret; } +static inline int +matchdep_str(const char *pattern, const char *string, int flags) +{ + if (flags & SELECTION_GLOB) + { + int globflags = (flags & SELECTION_NOCASE) != 0 ? FNM_CASEFOLD : 0; + return fnmatch(pattern, string, globflags) == 0 ? 1 : 0; + } + if (flags & SELECTION_NOCASE) + return strcasecmp(pattern, string) == 0 ? 1 : 0; + return strcmp(pattern, string) == 0 ? 1 : 0; +} + static int matchdep(Pool *pool, Id id, char *rname, int rflags, char *revr, int flags) { @@ -899,14 +912,7 @@ matchdep(Pool *pool, Id id, char *rname, int rflags, char *revr, int flags) } return 1; } - if (flags & SELECTION_GLOB) - { - int globflags = (flags & SELECTION_NOCASE) != 0 ? FNM_CASEFOLD : 0; - return fnmatch(rname, pool_id2str(pool, id), globflags) == 0 ? 1 : 0; - } - if (flags & SELECTION_NOCASE) - return strcasecmp(rname, pool_id2str(pool, id)) == 0 ? 1 : 0; - return strcmp(rname, pool_id2str(pool, id)) == 0 ? 1 : 0; + return matchdep_str(rname, pool_id2str(pool, id), flags); } /* @@ -917,22 +923,25 @@ matchdep(Pool *pool, Id id, char *rname, int rflags, char *revr, int flags) int selection_make_matchdeps(Pool *pool, Queue *selection, const char *name, int flags, int keyname, int marker) { - char *rname, *r; + char *rname, *r = 0; int rflags = 0; Id p; Queue q; queue_empty(selection); rname = solv_strdup(name); - if ((r = strpbrk(rname, "<=>")) != 0) + if (!(flags & SELECTION_MATCH_DEPSTR)) { - if ((r = splitrel(rname, r, &rflags)) == 0) + if ((r = strpbrk(rname, "<=>")) != 0) { - solv_free(rname); - return 0; + if ((r = splitrel(rname, r, &rflags)) == 0) + { + solv_free(rname); + return 0; + } } } - if ((flags & SELECTION_GLOB) != 0 && !strpbrk(name, "[*?") != 0) + if ((flags & SELECTION_GLOB) != 0 && !strpbrk(rname, "[*?") != 0) flags &= ~SELECTION_GLOB; queue_init(&q); @@ -957,6 +966,12 @@ selection_make_matchdeps(Pool *pool, Queue *selection, const char *name, int fla for (i = 0; i < q.count; i++) { Id id = q.elements[i]; + if ((flags & SELECTION_MATCH_DEPSTR) != 0) + { + if (matchdep_str(rname, pool_dep2str(pool, id), flags)) + break; + continue; + } if (matchdep(pool, id, rname, rflags, r, flags)) break; } @@ -972,6 +987,56 @@ selection_make_matchdeps(Pool *pool, Queue *selection, const char *name, int fla return SELECTION_PROVIDES; } +int +selection_make_matchdepid(Pool *pool, Queue *selection, Id dep, int flags, int keyname, int marker) +{ + Id p; + Queue q; + + queue_empty(selection); + if (!dep) + return 0; + queue_init(&q); + FOR_POOL_SOLVABLES(p) + { + Solvable *s = pool->solvables + p; + int i; + + if (s->repo != pool->installed && !pool_installable(pool, s)) + { + if (!(flags & SELECTION_SOURCE_ONLY) || (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)) + continue; + if (pool_disabled_solvable(pool, s)) + continue; + } + if ((flags & SELECTION_INSTALLED_ONLY) != 0 && s->repo != pool->installed) + continue; + if ((s->arch == ARCH_SRC || s->arch == ARCH_NOSRC) && !(flags & SELECTION_SOURCE_ONLY) && !(flags & SELECTION_WITH_SOURCE)) + continue; + queue_empty(&q); + repo_lookup_deparray(s->repo, p, keyname, &q, marker); + for (i = 0; i < q.count; i++) + { + if ((flags & SELECTION_MATCH_DEPSTR) != 0) /* mis-use */ + { + if (q.elements[i] == dep) + break; + continue; + } + if (pool_match_dep(pool, q.elements[i], dep)) + break; + } + if (i < q.count) + queue_push2(selection, SOLVER_SOLVABLE | SOLVER_NOAUTOSET, p); + } + queue_free(&q); + if (!selection->count) + return 0; + if ((flags & SELECTION_FLAT) != 0) + selection_flatten(pool, selection); + return SELECTION_PROVIDES; +} + static inline int pool_is_kind(Pool *pool, Id name, Id kind) { diff --git a/src/selection.h b/src/selection.h index fc2b15d..0dd6150 100644 --- a/src/selection.h +++ b/src/selection.h @@ -33,9 +33,11 @@ extern "C" { #define SELECTION_SOURCE_ONLY (1 << 12) #define SELECTION_WITH_SOURCE (1 << 13) #define SELECTION_SKIP_KIND (1 << 14) +#define SELECTION_MATCH_DEPSTR (1 << 15) extern int selection_make(Pool *pool, Queue *selection, const char *name, int flags); extern int selection_make_matchdeps(Pool *pool, Queue *selection, const char *name, int flags, int keyname, int marker); +extern int selection_make_matchdepid(Pool *pool, Queue *selection, Id dep, int flags, int keyname, int marker); extern void selection_filter(Pool *pool, Queue *sel1, Queue *sel2); extern void selection_add(Pool *pool, Queue *sel1, Queue *sel2); diff --git a/src/solver.c b/src/solver.c index d5989cc..4f849ec 100644 --- a/src/solver.c +++ b/src/solver.c @@ -1432,6 +1432,8 @@ reorder_dq_for_jobrules(Solver *solv, int level, Queue *dq) solv->recommends_index = -1; queue_truncate(&solv->decisionq, decisionqcount); } + /* but obey favored maps */ + policy_prefer_favored(solv, dq); } /*------------------------------------------------------------------- @@ -1701,6 +1703,7 @@ solver_free(Solver *solv) queuep_free(&solv->recommendscplxq); queuep_free(&solv->suggestscplxq); queuep_free(&solv->brokenorphanrules); + queuep_free(&solv->favorq); map_free(&solv->recommendsmap); map_free(&solv->suggestsmap); @@ -1716,6 +1719,8 @@ solver_free(Solver *solv) map_free(&solv->droporphanedmap); map_free(&solv->cleandepsmap); map_free(&solv->allowuninstallmap); + map_free(&solv->favormap); + map_free(&solv->isdisfavormap); solv_free(solv->decisionmap); solv_free(solv->rules); @@ -1779,6 +1784,8 @@ solver_get_flag(Solver *solv, int flag) return solv->do_yum_obsoletes; case SOLVER_FLAG_NEED_UPDATEPROVIDE: return solv->needupdateprovide; + case SOLVER_FLAG_URPM_REORDER: + return solv->urpmreorder; default: break; } @@ -1857,6 +1864,9 @@ solver_set_flag(Solver *solv, int flag, int value) case SOLVER_FLAG_NEED_UPDATEPROVIDE: solv->needupdateprovide = value; break; + case SOLVER_FLAG_URPM_REORDER: + solv->urpmreorder = value; + break; default: break; } @@ -2063,6 +2073,22 @@ do_complex_recommendations(Solver *solv, Id rec, Map *m, int noselected) #endif +static void +prune_disfavored(Solver *solv, Queue *plist) +{ + int i, j; + if (!solv->isdisfavormap.size) + return; + for (i = j = 0; i < plist->count; i++) + { + Id p = plist->elements[i]; + if (!MAPTST(&solv->isdisfavormap, p)) + plist->elements[j++] = p; + } + if (i != j) + queue_truncate(plist, j); +} + /*------------------------------------------------------------------- * * solver_run_sat @@ -2522,10 +2548,16 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) continue; if (solv->dupmap_all && solv->installed && s->repo == solv->installed && (solv->droporphanedmap_all || (solv->droporphanedmap.size && MAPTST(&solv->droporphanedmap, i - solv->installed->start)))) continue; + if (solv->isdisfavormap.size && MAPTST(&solv->isdisfavormap, i)) + continue; /* disfavored supplements, do not install */ queue_push(&dqs, i); } } + /* filter out disfavored recommended packages */ + if (dq.count && solv->isdisfavormap.size) + prune_disfavored(solv, &dq); + /* filter out all packages obsoleted by installed packages */ /* this is no longer needed if we have reverse obsoletes */ if ((dqs.count || dq.count) && solv->installed) @@ -2604,6 +2636,26 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) dqs.count = j; } + /* implicitobsoleteusescolors doesn't mix well with supplements. + * filter supplemented packages where we already decided + * to install a different architecture */ + if (dqs.count && pool->implicitobsoleteusescolors) + { + for (i = j = 0; i < dqs.count; i++) + { + Id p2, pp2; + p = dqs.elements[i]; + s = pool->solvables + p; + FOR_PROVIDES(p2, pp2, s->name) + if (solv->decisionmap[p2] > 0 && pool->solvables[p2].name == s->name && pool->solvables[p2].arch != s->arch) + break; + if (p2) + continue; /* ignore this package */ + dqs.elements[j++] = p; + } + dqs.count = j; + } + /* make dq contain both recommended and supplemented pkgs */ if (dqs.count) { @@ -2636,11 +2688,22 @@ solver_run_sat(Solver *solv, int disablerules, int doweak) for (i = 0; i < dq.count; i++) MAPSET(&dqmap, dq.elements[i]); - /* install all supplemented packages */ + /* prune dqs so that it only contains the best versions */ + for (i = j = 0; i < dqs.count; i++) + { + p = dqs.elements[i]; + if (MAPTST(&dqmap, p)) + dqs.elements[j++] = p; + } + dqs.count = j; + + /* install all supplemented packages, but order first */ + if (dqs.count > 1) + policy_filter_unwanted(solv, &dqs, POLICY_MODE_SUPPLEMENT); for (i = 0; i < dqs.count; i++) { p = dqs.elements[i]; - if (solv->decisionmap[p] || !MAPTST(&dqmap, p)) + if (solv->decisionmap[p]) continue; POOL_DEBUG(SOLV_DEBUG_POLICY, "installing supplemented %s\n", pool_solvid2str(pool, p)); olevel = level; @@ -3327,6 +3390,42 @@ add_complex_jobrules(Solver *solv, Id dep, int flags, int jobidx, int weak) } #endif +/* sort by package id, last entry wins */ +static int +setup_favormaps_cmp(const void *ap, const void *bp, void *dp) +{ + const Id *a = ap, *b = bp; + if ((*a - *b) != 0) + return *a - *b; + return (b[1] < 0 ? -b[1] : b[1]) - (a[1] < 0 ? -a[1] : a[1]); +} + +static void +setup_favormaps(Solver *solv) +{ + Queue *q = solv->favorq; + Pool *pool = solv->pool; + int i; + Id oldp = 0; + if (q->count > 2) + solv_sort(q->elements, q->count / 2, 2 * sizeof(Id), setup_favormaps_cmp, solv); + map_grow(&solv->favormap, pool->nsolvables); + for (i = 0; i < q->count; i += 2) + { + Id p = q->elements[i]; + if (p == oldp) + continue; + oldp = p; + MAPSET(&solv->favormap, p); + if (q->elements[i + 1] < 0) + { + if (!solv->isdisfavormap.size) + map_grow(&solv->isdisfavormap, pool->nsolvables); + MAPSET(&solv->isdisfavormap, p); + } + } +} + /* * * solve job queue @@ -3400,6 +3499,8 @@ solver_solve(Solver *solv, Queue *job) map_zerosize(&solv->allowuninstallmap); map_zerosize(&solv->cleandepsmap); map_zerosize(&solv->weakrulemap); + map_zerosize(&solv->favormap); + map_zerosize(&solv->isdisfavormap); queue_empty(&solv->weakruleq); solv->watches = solv_free(solv->watches); queue_empty(&solv->ruletojob); @@ -3935,6 +4036,21 @@ solver_solve(Solver *solv, Queue *job) case SOLVER_ALLOWUNINSTALL: POOL_DEBUG(SOLV_DEBUG_JOB, "job: allowuninstall %s\n", solver_select2str(pool, select, what)); break; + case SOLVER_FAVOR: + case SOLVER_DISFAVOR: + POOL_DEBUG(SOLV_DEBUG_JOB, "job: %s %s\n", (how & SOLVER_JOBMASK) == SOLVER_FAVOR ? "favor" : "disfavor", solver_select2str(pool, select, what)); + FOR_JOB_SELECT(p, pp, select, what) + { + int j; + if (!solv->favorq) + { + solv->favorq = solv_calloc(1, sizeof(Queue)); + queue_init(solv->favorq); + } + j = solv->favorq->count + 1; + queue_push2(solv->favorq, p, (how & SOLVER_JOBMASK) == SOLVER_FAVOR ? j : -j); + } + break; default: POOL_DEBUG(SOLV_DEBUG_JOB, "job: unknown job\n"); break; @@ -3955,6 +4071,10 @@ solver_solve(Solver *solv, Queue *job) assert(solv->ruletojob.count == solv->nrules - solv->jobrules); solv->jobrules_end = solv->nrules; + /* transform favorq into two maps */ + if (solv->favorq) + setup_favormaps(solv); + /* now create infarch and dup rules */ if (!solv->noinfarchcheck) { @@ -5157,6 +5277,12 @@ pool_job2str(Pool *pool, Id how, Id what, Id flagmask) case SOLVER_ALLOWUNINSTALL: strstart = "allow deinstallation of "; break; + case SOLVER_FAVOR: + strstart = "favor "; + break; + case SOLVER_DISFAVOR: + strstart = "disfavor "; + break; default: strstart = "unknown job "; break; diff --git a/src/solver.h b/src/solver.h index 2ae9c8d..3495fd8 100644 --- a/src/solver.h +++ b/src/solver.h @@ -167,6 +167,7 @@ struct _Solver { int noautotarget; /* true: do not assume targeted for up/dup jobs that contain no installed solvable */ int focus_installed; /* true: resolve update rules first */ int do_yum_obsoletes; /* true: add special yumobs rules */ + int urpmreorder; /* true: do special urpm package reordering */ Map dupmap; /* dup these packages*/ int dupmap_all; /* dup all packages */ @@ -199,6 +200,9 @@ struct _Solver { Map allowuninstallmap; /* ok to uninstall those */ int allowuninstall_all; + Queue *favorq; + Map favormap; /* favored / disfavored packages */ + Map isdisfavormap; #endif /* LIBSOLV_INTERNAL */ }; @@ -229,6 +233,8 @@ typedef struct _Solver Solver; #define SOLVER_DROP_ORPHANED 0x0900 #define SOLVER_USERINSTALLED 0x0a00 #define SOLVER_ALLOWUNINSTALL 0x0b00 +#define SOLVER_FAVOR 0x0c00 +#define SOLVER_DISFAVOR 0x0d00 #define SOLVER_JOBMASK 0xff00 @@ -302,6 +308,7 @@ typedef struct _Solver Solver; #define SOLVER_FLAG_FOCUS_INSTALLED 20 #define SOLVER_FLAG_YUM_OBSOLETES 21 #define SOLVER_FLAG_NEED_UPDATEPROVIDE 22 +#define SOLVER_FLAG_URPM_REORDER 23 #define GET_USERINSTALLED_NAMES (1 << 0) /* package names instead of ids */ #define GET_USERINSTALLED_INVERTED (1 << 1) /* autoinstalled */ |