diff options
-rw-r--r-- | src/policy.c | 9 | ||||
-rw-r--r-- | src/pool.c | 42 | ||||
-rw-r--r-- | src/pool.h | 10 | ||||
-rw-r--r-- | src/solvable.c | 8 | ||||
-rw-r--r-- | src/solver.c | 275 | ||||
-rw-r--r-- | src/solver.h | 14 | ||||
-rw-r--r-- | src/solverdebug.c | 6 |
7 files changed, 298 insertions, 66 deletions
diff --git a/src/policy.c b/src/policy.c index c6f9a10..176601b 100644 --- a/src/policy.c +++ b/src/policy.c @@ -116,7 +116,7 @@ prune_to_recommended(Solver *solv, Queue *plist) Pool *pool = solv->pool; int i, j; Solvable *s; - Id p, *pp, rec, *recp, sug, *sugp; + Id p, pp, rec, *recp, sug, *sugp; if (solv->recommends_index < 0) { @@ -241,7 +241,7 @@ prune_to_best_version(Solver *solv, Queue *plist) /* FIXME do not prune cycles */ for (i = 0; i < plist->count; i++) { - Id p, *pp, obs, *obsp; + Id p, pp, obs, *obsp; s = pool->solvables + plist->elements[i]; if (!s->obsoletes) continue; @@ -401,7 +401,7 @@ policy_findupdatepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all) { /* installed packages get a special upgrade allowed rule */ Pool *pool = solv->pool; - Id p, *pp, n, p2, *pp2; + Id p, pp, n, p2, pp2; Id obs, *obsp; Solvable *ps; @@ -467,7 +467,8 @@ policy_findupdatepackages(Solver *solv, Solvable *s, Queue *qs, int allow_all) return; if (solv->obsoletes && solv->obsoletes[n - solv->installed->start]) { - for (pp = solv->obsoletes_data + solv->obsoletes[n - solv->installed->start]; (p = *pp++) != 0;) + Id *opp; + for (opp = solv->obsoletes_data + solv->obsoletes[n - solv->installed->start]; (p = *opp++) != 0;) { ps = pool->solvables + p; if (!allow_all && !solv->allowarchchange && s->arch != ps->arch && policy_illegal_archchange(solv, s, ps)) @@ -456,7 +456,7 @@ pool_match_nevr_rel(Pool *pool, Solvable *s, Id d) * */ -Id * +Id pool_addrelproviders(Pool *pool, Id d) { Reldep *rd = GETRELDEP(pool, d); @@ -467,7 +467,7 @@ pool_addrelproviders(Pool *pool, Id d) Id evr = rd->evr; int flags = rd->flags; Id pid, *pidp; - Id p, *pp, *pp2, *pp3; + Id p, wp, *pp, *pp2, *pp3; d = GETRELID(d); queue_init_buffer(&plist, buf, sizeof(buf)/sizeof(*buf)); @@ -475,8 +475,8 @@ pool_addrelproviders(Pool *pool, Id d) { case REL_AND: case REL_WITH: - pp = pool_whatprovides(pool, name); - pp2 = pool_whatprovides(pool, evr); + pp = pool->whatprovidesdata + pool_whatprovides(pool, name); + pp2 = pool->whatprovidesdata + pool_whatprovides(pool, evr); while ((p = *pp++) != 0) { for (pp3 = pp2; *pp3;) @@ -488,19 +488,19 @@ pool_addrelproviders(Pool *pool, Id d) } break; case REL_OR: - pp = pool_whatprovides(pool, name); + pp = pool->whatprovidesdata + pool_whatprovides(pool, name); while ((p = *pp++) != 0) queue_push(&plist, p); - pp = pool_whatprovides(pool, evr); + pp = pool->whatprovidesdata + pool_whatprovides(pool, evr); while ((p = *pp++) != 0) queue_pushunique(&plist, p); break; case REL_NAMESPACE: if (name == NAMESPACE_OTHERPROVIDERS) { - pp = pool_whatprovides(pool, evr); - pool->whatprovides_rel[d] = pp - pool->whatprovidesdata; - return pp; + wp = pool_whatprovides(pool, evr); + pool->whatprovides_rel[d] = wp; + return wp; } if (pool->nscallback) { @@ -514,7 +514,7 @@ pool_addrelproviders(Pool *pool, Id d) { queue_free(&plist); pool->whatprovides_rel[d] = p; - return pool->whatprovidesdata + p; + return p; } if (p == 1) queue_push(&plist, SYSTEMSOLVABLE); @@ -537,17 +537,21 @@ pool_addrelproviders(Pool *pool, Id d) } break; } - pp = pp2 = pool_whatprovides(pool, name); + wp = pool_whatprovides(pool, name); + pp = pool->whatprovidesdata + wp; while ((p = *pp++) != 0) { Solvable *s = pool->solvables + p; if (s->arch == evr) queue_push(&plist, p); else - pp2 = 0; + wp = 0; + } + if (wp) + { + pool->whatprovides_rel[d] = wp; + return wp; } - if (pp2) - return pp2; break; default: break; @@ -559,7 +563,7 @@ pool_addrelproviders(Pool *pool, Id d) #endif if (flags && flags < 8) { - pp = pool_whatprovides(pool, name); + pp = pool->whatprovidesdata + pool_whatprovides(pool, name); while (ISRELDEP(name)) { rd = GETRELDEP(pool, name); @@ -635,7 +639,7 @@ pool_addrelproviders(Pool *pool, Id d) pool->whatprovides_rel[d] = pool_queuetowhatprovides(pool, &plist); queue_free(&plist); - return pool->whatprovidesdata + pool->whatprovides_rel[d]; + return pool->whatprovides_rel[d]; } /*************************************************************************/ @@ -1260,7 +1264,7 @@ pool_calc_duchanges(Pool *pool, Repo *oldinstalled, Map *installedmap, DUChanges repo_search(s->repo, sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd); if (!cbd.hasdu && oldinstalled) { - Id op, *opp; + Id op, opp; /* no du data available, ignore data of all installed solvables we obsolete */ if (!ignoredu.map) map_init(&ignoredu, oldinstalled->end - oldinstalled->start); @@ -1343,7 +1347,7 @@ static inline Id dep2name(Pool *pool, Id dep) static inline int providedbyinstalled(Pool *pool, unsigned char *map, Id dep) { - Id p, *pp; + Id p, pp; int r = 0; FOR_PROVIDES(p, pp, dep) { @@ -1387,7 +1391,7 @@ pool_trivial_installable(Pool *pool, Repo *oldinstalled, Map *installedmap, Queu conp = s->repo->idarraydata + s->conflicts; while ((con = *conp++) != 0) { - dp = pool_whatprovides(pool, con); + dp = pool->whatprovidesdata + pool_whatprovides(pool, con); for (; *dp; dp++) map[p] |= 2; /* XXX: self conflict ? */ } @@ -221,16 +221,16 @@ static inline int pool_installable(Pool *pool, Solvable *s) return 1; } -extern Id *pool_addrelproviders(Pool *pool, Id d); +extern Id pool_addrelproviders(Pool *pool, Id d); -static inline Id *pool_whatprovides(Pool *pool, Id d) +static inline Id pool_whatprovides(Pool *pool, Id d) { Id v; if (!ISRELDEP(d)) - return pool->whatprovidesdata + pool->whatprovides[d]; + return pool->whatprovides[d]; v = GETRELID(d); if (pool->whatprovides_rel[v]) - return pool->whatprovidesdata + pool->whatprovides_rel[v]; + return pool->whatprovides_rel[v]; return pool_addrelproviders(pool, d); } @@ -273,7 +273,7 @@ void pool_trivial_installable(Pool *pool, struct _Repo *oldinstalled, Map *insta /* loop over all providers of d */ #define FOR_PROVIDES(v, vp, d) \ - for (vp = pool_whatprovides(pool, d) ; (v = *vp++) != 0; ) + for (vp = pool_whatprovides(pool, d) ; (v = pool->whatprovidesdata[vp++]) != 0; ) #define POOL_DEBUG(type, ...) do {if ((pool->debugmask & (type)) != 0) pool_debug(pool, (type), __VA_ARGS__);} while (0) #define IF_POOLDEBUG(type) if ((pool->debugmask & (type)) != 0) diff --git a/src/solvable.c b/src/solvable.c index 2ca310c..f595f1c 100644 --- a/src/solvable.c +++ b/src/solvable.c @@ -397,7 +397,7 @@ static inline Id dep2name(Pool *pool, Id dep) static inline int providedbyinstalled(Pool *pool, Map *installed, Id dep) { - Id p, *pp; + Id p, pp; FOR_PROVIDES(p, pp, dep) { if (p == SYSTEMSOLVABLE) @@ -429,7 +429,7 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm { Pool *pool = s->repo->pool; Solvable *s2; - Id p, *pp, *dp; + Id p, pp, *dp; Id *reqp, req; Id *conp, con; Id *obsp, obs; @@ -503,7 +503,7 @@ solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsm conp = s2->repo->idarraydata + s2->conflicts; while ((con = *conp++) != 0) { - dp = pool_whatprovides(pool, con); + dp = pool->whatprovidesdata + pool_whatprovides(pool, con); for (; *dp; dp++) if (*dp == p) return 0; @@ -597,7 +597,7 @@ pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *con conp = s->repo->idarraydata + s->conflicts; while ((con = *conp++) != 0) { - dp = pool_whatprovides(pool, con); + dp = pool->whatprovidesdata + pool_whatprovides(pool, con); for (; *dp; dp++) MAPSET(conflictsmap, *dp); } diff --git a/src/solver.c b/src/solver.c index 9970faf..6cfaf11 100644 --- a/src/solver.c +++ b/src/solver.c @@ -25,8 +25,6 @@ #include "policy.h" #include "solverdebug.h" -#define CODE10 0 /* set to '1' to enable patch atoms */ - #define RULES_BLOCK 63 /******************************************************************** @@ -43,7 +41,7 @@ int solver_splitprovides(Solver *solv, Id dep) { Pool *pool = solv->pool; - Id p, *pp; + Id p, pp; Reldep *rd; Solvable *s; @@ -73,7 +71,7 @@ solver_dep_installed(Solver *solv, Id dep) { #if 0 Pool *pool = solv->pool; - Id p, *pp; + Id p, pp; if (ISRELDEP(dep)) { @@ -108,7 +106,7 @@ static inline int dep_possible(Solver *solv, Id dep, Map *m) { Pool *pool = solv->pool; - Id p, *pp; + Id p, pp; if (ISRELDEP(dep)) { @@ -867,7 +865,7 @@ disableupdaterules(Solver *solv, Queue *job, int jobidx) { Pool *pool = solv->pool; int i, j; - Id how, select, what, p, *pp; + Id how, select, what, p, pp; Solvable *s; Repo *installed; Rule *r; @@ -1057,7 +1055,7 @@ makemultiversionconflict(Solver *solv, Id n, Id con) Pool *pool = solv->pool; Solvable *s, *sn; Queue q; - Id p, *pp, qbuf[64]; + Id p, pp, qbuf[64]; sn = pool->solvables + n; queue_init_buffer(&q, qbuf, sizeof(qbuf)/sizeof(*qbuf)); @@ -1117,9 +1115,6 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) * 0 = yes, 1 = no */ int dontfix; -#if CODE10 - int patchatom; -#endif /* Id var and pointer for each dependency * (not used in parallel) */ @@ -1129,7 +1124,7 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) Id rec, *recp; Id sug, *sugp; /* var and ptr for loops */ - Id p, *pp; + Id p, pp; /* ptr to 'whatprovides' */ Id *dp; /* Id for current solvable 's' */ @@ -1185,18 +1180,11 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) continue; /* find list of solvables providing 'req' */ - dp = pool_whatprovides(pool, req); + dp = pool->whatprovidesdata + pool_whatprovides(pool, req); if (*dp == SYSTEMSOLVABLE) /* always installed */ continue; -#if CODE10 - if (patchatom) - { - addpatchatomrequires(solv, s, dp, &workq, m); - continue; - } -#endif if (dontfix) { /* the strategy here is to not insist on dependencies @@ -1264,6 +1252,8 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) /* we treat conflicts in patches a bit differen: * - nevr matching * - multiversion handling + * XXX: we should really handle this different, looking + * at the name is a bad hack */ if (!strncmp("patch:", id2str(pool, s->name), 6)) ispatch = 1; @@ -2726,7 +2716,7 @@ run_solver(Solver *solv, int disablerules, int doweak) if (solv->decisionmap[i] > 0) { /* installed, check for recommends */ - Id *recp, rec, *pp, p; + Id *recp, rec, pp, p; s = pool->solvables + i; if (solv->ignorealreadyrecommended && s->repo == solv->installed) continue; @@ -3351,7 +3341,7 @@ solver_problemruleinfo(Solver *solv, Queue *job, Id rid, Id *depp, Id *sourcep, Rule *r; Solvable *s; int dontfix = 0; - Id p, d, w2, *pp, req, *reqp, con, *conp, obs, *obsp, *dp; + Id p, d, w2, pp, req, *reqp, con, *conp, obs, *obsp, *dp; assert(rid > 0); if (rid >= solv->jobrules && rid < solv->jobrules_end) @@ -3401,7 +3391,7 @@ solver_problemruleinfo(Solver *solv, Queue *job, Id rid, Id *depp, Id *sourcep, { if (req == SOLVABLE_PREREQMARKER) continue; - dp = pool_whatprovides(pool, req); + dp = pool->whatprovidesdata + pool_whatprovides(pool, req); if (*dp == 0) break; } @@ -3573,7 +3563,7 @@ solver_problemruleinfo(Solver *solv, Queue *job, Id rid, Id *depp, Id *sourcep, { if (req == SOLVABLE_PREREQMARKER) continue; - dp = pool_whatprovides(pool, req); + dp = pool->whatprovidesdata + pool_whatprovides(pool, req); if (d == 0) { if (*dp == r->w2 && dp[1] == 0) @@ -3711,7 +3701,7 @@ create_obsolete_index(Solver *solv) Pool *pool = solv->pool; Solvable *s; Repo *installed = solv->installed; - Id p, *pp, obs, *obsp, *obsoletes, *obsoletes_data; + Id p, pp, obs, *obsp, *obsoletes, *obsoletes_data; int i, n; if (!installed || !installed->nsolvables) @@ -3916,7 +3906,7 @@ solver_solve(Solver *solv, Queue *job) int oldnrules; Map addedmap; /* '1' == have rpm-rules for solvable */ Map installcandidatemap; - Id how, what, select, name, weak, p, *pp, d; + Id how, what, select, name, weak, p, pp, d; Queue q, redoq; Solvable *s; int goterase; @@ -4369,7 +4359,7 @@ solver_solve(Solver *solv, Queue *job) * solver run */ if (redoq.count || solv->dontinstallrecommended || !solv->dontshowinstalledrecommended || solv->ignorealreadyrecommended) { - Id rec, *recp, p, *pp; + Id rec, *recp, p, pp; /* create map of all recommened packages */ solv->recommends_index = -1; @@ -4434,7 +4424,7 @@ solver_solve(Solver *solv, Queue *job) if (1) { - Id sug, *sugp, p, *pp; + Id sug, *sugp, p, pp; /* create map of all suggests that are still open */ solv->recommends_index = -1; @@ -4566,4 +4556,235 @@ solver_calc_installsizechange(Solver *solv) return change; } +#define FIND_INVOLVED_DEBUG 0 +void +solver_find_involved(Solver *solv, Queue *installedq, Solvable *ts, Queue *q) +{ + Pool *pool = solv->pool; + Map im; + Map installedm; + Solvable *s; + Queue iq; + Queue installedq_internal; + Id tp, ip, p, pp, req, *reqp, sup, *supp; + int i, count; + + tp = ts - pool->solvables; + queue_init(&iq); + queue_init(&installedq_internal); + map_init(&im, pool->nsolvables); + map_init(&installedm, pool->nsolvables); + + if (!installedq) + { + installedq = &installedq_internal; + if (solv->installed) + { + for (ip = solv->installed->start; ip < solv->installed->end; ip++) + { + s = pool->solvables + ip; + if (s->repo != solv->installed) + continue; + queue_push(installedq, ip); + } + } + } + for (i = 0; i < installedq->count; i++) + { + ip = installedq->elements[i]; + MAPSET(&installedm, ip); + MAPSET(&im, ip); + } + + queue_push(&iq, ts - pool->solvables); + while (iq.count) + { + ip = queue_shift(&iq); + if (!MAPTST(&im, ip)) + continue; + if (!MAPTST(&installedm, ip)) + continue; + MAPCLR(&im, ip); + s = pool->solvables + ip; +#if FIND_INVOLVED_DEBUG + printf("hello %s\n", solvable2str(pool, s)); +#endif + if (s->requires) + { + reqp = s->repo->idarraydata + s->requires; + while ((req = *reqp++) != 0) + { + if (req == SOLVABLE_PREREQMARKER) + continue; + /* count number of installed packages that match */ + count = 0; + FOR_PROVIDES(p, pp, req) + if (MAPTST(&installedm, p)) + count++; + if (count > 1) + continue; + FOR_PROVIDES(p, pp, req) + { + if (MAPTST(&im, p)) + { +#if FIND_INVOLVED_DEBUG + printf("%s requires %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p)); +#endif + queue_push(&iq, p); + } + } + } + } + if (s->recommends) + { + reqp = s->repo->idarraydata + s->recommends; + while ((req = *reqp++) != 0) + { + count = 0; + FOR_PROVIDES(p, pp, req) + if (MAPTST(&installedm, p)) + count++; + if (count > 1) + continue; + FOR_PROVIDES(p, pp, req) + { + if (MAPTST(&im, p)) + { +#if FIND_INVOLVED_DEBUG + printf("%s recommends %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p)); +#endif + queue_push(&iq, p); + } + } + } + } + if (!iq.count) + { + /* supplements pass */ + for (i = 0; i < installedq->count; i++) + { + ip = installedq->elements[i]; + s = pool->solvables + ip; + if (!s->supplements) + continue; + if (!MAPTST(&im, ip)) + continue; + supp = s->repo->idarraydata + s->supplements; + while ((sup = *supp++) != 0) + if (!dep_possible(solv, sup, &im) && dep_possible(solv, sup, &installedm)) + break; + /* no longer supplemented, also erase */ + if (sup) + { +#if FIND_INVOLVED_DEBUG + printf("%s supplemented\n", solvable2str(pool, pool->solvables + ip)); +#endif + queue_push(&iq, ip); + } + } + } + } + + for (i = 0; i < installedq->count; i++) + { + ip = installedq->elements[i]; + if (MAPTST(&im, ip)) + queue_push(&iq, ip); + } + + while (iq.count) + { + ip = queue_shift(&iq); + if (!MAPTST(&installedm, ip)) + continue; + s = pool->solvables + ip; +#if FIND_INVOLVED_DEBUG + printf("bye %s\n", solvable2str(pool, s)); +#endif + if (s->requires) + { + reqp = s->repo->idarraydata + s->requires; + while ((req = *reqp++) != 0) + { + FOR_PROVIDES(p, pp, req) + { + if (!MAPTST(&im, p)) + { + if (p == tp) + continue; +#if FIND_INVOLVED_DEBUG + printf("%s requires %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p)); +#endif + MAPSET(&im, p); + queue_push(&iq, p); + } + } + } + } + if (s->recommends) + { + reqp = s->repo->idarraydata + s->recommends; + while ((req = *reqp++) != 0) + { + FOR_PROVIDES(p, pp, req) + { + if (!MAPTST(&im, p)) + { + if (p == tp) + continue; +#if FIND_INVOLVED_DEBUG + printf("%s recommends %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p)); +#endif + MAPSET(&im, p); + queue_push(&iq, p); + } + } + } + } + if (!iq.count) + { + /* supplements pass */ + for (i = 0; i < installedq->count; i++) + { + ip = installedq->elements[i]; + if (ip == tp) + continue; + s = pool->solvables + ip; + if (!s->supplements) + continue; + if (MAPTST(&im, ip)) + continue; + supp = s->repo->idarraydata + s->supplements; + while ((sup = *supp++) != 0) + if (dep_possible(solv, sup, &im)) + break; + if (sup) + { +#if FIND_INVOLVED_DEBUG + printf("%s supplemented\n", solvable2str(pool, pool->solvables + ip)); +#endif + MAPSET(&im, ip); + queue_push(&iq, ip); + } + } + } + } + + queue_free(&iq); + + /* convert map into result */ + for (i = 0; i < installedq->count; i++) + { + ip = installedq->elements[i]; + if (MAPTST(&im, ip)) + continue; + if (ip == ts - pool->solvables) + continue; + queue_push(q, ip); + } + map_free(&im); + map_free(&installedm); + queue_free(&installedq_internal); +} + /* EOF */ diff --git a/src/solver.h b/src/solver.h index 13366a3..9c0dd05 100644 --- a/src/solver.h +++ b/src/solver.h @@ -281,7 +281,7 @@ static inline int solver_dep_fulfilled(Solver *solv, Id dep) { Pool *pool = solv->pool; - Id p, *pp; + Id p, pp; if (ISRELDEP(dep)) { @@ -334,22 +334,28 @@ solver_is_enhancing(Solver *solv, Solvable *s) void solver_calc_duchanges(Solver *solv, DUChanges *mps, int nmps); int solver_calc_installsizechange(Solver *solv); +void solver_find_involved(Solver *solv, Queue *installedq, Solvable *s, Queue *q); + static inline void solver_create_state_maps(Solver *solv, Map *installedmap, Map *conflictsmap) { pool_create_state_maps(solv->pool, &solv->decisionq, installedmap, conflictsmap); } +/* iterate over all literals of a rule */ +/* WARNING: loop body must not relocate whatprovidesdata, e.g. by + * looking up the providers of a dependency */ #define FOR_RULELITERALS(l, dp, r) \ for (l = r->d < 0 ? -r->d - 1 : r->d, \ dp = !l ? &r->w2 : pool->whatprovidesdata + l, \ l = r->p; l; l = (dp != &r->w2 + 1 ? *dp++ : 0)) +/* iterate over all packages selected by a job */ #define FOR_JOB_SELECT(p, pp, select, what) \ - for (pp = (select == SOLVER_SOLVABLE ? pool->whatprovidesdata : \ - select == SOLVER_SOLVABLE_ONE_OF ? pool->whatprovidesdata + what : \ + for (pp = (select == SOLVER_SOLVABLE ? 0 : \ + select == SOLVER_SOLVABLE_ONE_OF ? what : \ pool_whatprovides(pool, what)), \ - p = (select == SOLVER_SOLVABLE ? what : *pp++) ; p ; p = *pp++) \ + p = (select == SOLVER_SOLVABLE ? what : pool->whatprovidesdata[pp++]) ; p ; p = pool->whatprovidesdata[pp++]) \ if (select != SOLVER_SOLVABLE_NAME || pool_match_nevr(pool, pool->solvables + p, what)) #ifdef __cplusplus diff --git a/src/solverdebug.c b/src/solverdebug.c index 2e314cf..42d48ba 100644 --- a/src/solverdebug.c +++ b/src/solverdebug.c @@ -51,7 +51,7 @@ solver_create_decisions_obsoletesmap(Solver *solv) { for (i = 0; i < solv->decisionq.count; i++) { - Id *pp, n; + Id pp, n; int noobs; n = solv->decisionq.elements[i]; @@ -80,7 +80,7 @@ solver_create_decisions_obsoletesmap(Solver *solv) for (i = 0; i < solv->decisionq.count; i++) { Id obs, *obsp; - Id *pp, n; + Id pp, n; n = solv->decisionq.elements[i]; if (n < 0) @@ -301,7 +301,7 @@ solver_printdecisions(Solver *solv) } else { - Id xp, *xpp; + Id xp, xpp; FOR_PROVIDES(xp, xpp, s->name) { Solvable *s2 = pool->solvables + xp; |