From ff47ba98ba911adcfe3b123357fd18054b9b43aa Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Wed, 14 Nov 2007 20:35:50 +0000 Subject: [PATCH] - allow repositories that don't consist of a single block of solvables --- src/pool.c | 2 +- src/pool.h | 2 +- src/repo.c | 56 ++++----- src/repo.h | 5 +- src/repo_solv.c | 18 +-- src/solver.c | 305 ++++++++++++++++++++++++++------------------------ tools/dumpsolv.c | 4 +- tools/mergesolv.c | 2 +- tools/repo_content.c | 5 + tools/repo_helix.c | 4 +- tools/repo_patchxml.c | 4 +- tools/repo_rpmdb.c | 6 +- tools/repo_rpmmd.c | 6 +- tools/repo_susetags.c | 6 +- tools/repo_write.c | 18 +-- tools/rpmdb2solv.c | 2 +- 16 files changed, 240 insertions(+), 205 deletions(-) diff --git a/src/pool.c b/src/pool.c index 1e694e9..765010a 100644 --- a/src/pool.c +++ b/src/pool.c @@ -121,7 +121,7 @@ pool_free(Pool *pool) pool_freewhatprovides(pool); pool_freeidhashes(pool); - pool_freeallrepos(pool); + pool_freeallrepos(pool, 1); xfree(pool->id2arch); xfree(pool->solvables); xfree(pool->stringspace); diff --git a/src/pool.h b/src/pool.h index f17ff84..2861c9b 100644 --- a/src/pool.h +++ b/src/pool.h @@ -166,7 +166,7 @@ extern Id *pool_addrelproviders(Pool *pool, Id d); static inline int pool_installable(Pool *pool, Solvable *s) { - if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC) + if (!s->arch || s->arch == ARCH_SRC || s->arch == ARCH_NOSRC) return 0; if (pool->id2arch && (s->arch > pool->lastarch || !pool->id2arch[s->arch])) return 0; diff --git a/src/repo.c b/src/repo.c index b9bdc28..8e05b66 100644 --- a/src/repo.c +++ b/src/repo.c @@ -41,6 +41,7 @@ repo_create(Pool *pool, const char *name) repo->name = name ? strdup(name) : 0; repo->pool = pool; repo->start = pool->nsolvables; + repo->end = pool->nsolvables; repo->nsolvables = 0; return repo; } @@ -246,54 +247,59 @@ repo_reserve_ids(Repo *repo, Offset olddeps, int num) /* - * remove repo from pool + * remove repo from pool, zero out solvables * */ void -repo_free(Repo *repo) +repo_free(Repo *repo, int reuseids) { Pool *pool = repo->pool; - int i, nsolvables; + Solvable *s; + int i; pool_freewhatprovides(pool); - for (i = 0; i < pool->nrepos; i++) /* find repo in pool */ + if (reuseids && repo->end == pool->nsolvables) { - if (pool->repos[i] == repo) - break; + /* it's ok to reuse the ids. As this is the last repo, we can + just shrink the solvable array */ + for (i = repo->end - 1, s = pool->solvables + i; i >= repo->start; i--, s--) + if (s->repo != repo) + break; + repo->end = i + 1; + pool->nsolvables = i + 1; } + /* zero out solvables belonging to this repo */ + for (i = repo->start, s = pool->solvables + i; i < repo->end; i++, s++) + if (s->repo == repo) + memset(s, 0, sizeof(*s)); + for (i = 0; i < pool->nrepos; i++) /* find repo in pool */ + if (pool->repos[i] == repo) + break; if (i == pool->nrepos) /* repo not in pool, return */ return; - - /* close gap - * all repos point into pool->solvables _relatively_ to repo->start - * so closing the gap only needs adaption of repo->start for all - * other repos. - */ - - nsolvables = repo->nsolvables; - if (pool->nsolvables > repo->start + nsolvables) - memmove(pool->solvables + repo->start, pool->solvables + repo->start + nsolvables, (pool->nsolvables - repo->start - nsolvables) * sizeof(Solvable)); - pool->nsolvables -= nsolvables; - - for (; i < pool->nrepos - 1; i++) - { - pool->repos[i] = pool->repos[i + 1]; /* remove repo */ - pool->repos[i]->start -= nsolvables; /* adapt start offset of remaining repos */ - } - pool->nrepos = i; + if (i < pool->nrepos - 1) + memmove(pool->repos + i, pool->repos + i + 1, (pool->nrepos - 1 - i) * sizeof(Repo *)); + pool->nrepos--; repo_freedata(repo); } void -pool_freeallrepos(Pool *pool) +pool_freeallrepos(Pool *pool, int reuseids) { int i; + + pool_freewhatprovides(pool); for (i = 0; i < pool->nrepos; i++) repo_freedata(pool->repos[i]); + /* the first two solvables don't belong to a repo */ + if (pool->nsolvables > 2 && !reuseids) + memset(pool->solvables + 2, 0, (pool->nsolvables - 2) * sizeof(Solvable)); pool->repos = xfree(pool->repos); pool->nrepos = 0; + if (reuseids) + pool->nsolvables = 2; } Offset diff --git a/src/repo.h b/src/repo.h index 85b011d..1d51f13 100644 --- a/src/repo.h +++ b/src/repo.h @@ -19,6 +19,7 @@ typedef struct _Repo { const char *name; struct _Pool *pool; /* pool containing repo data */ int start; /* start of this repo solvables within pool->solvables */ + int end; /* last solvable + 1 of this repo */ int nsolvables; /* number of solvables repo is contributing to pool */ int priority; /* priority of this repo */ @@ -31,14 +32,14 @@ typedef struct _Repo { } Repo; extern Repo *repo_create(Pool *pool, const char *name); -extern void repo_free(Repo *repo); +extern void repo_free(Repo *repo, int reuseids); extern Offset repo_addid(Repo *repo, Offset olddeps, Id id); extern Offset repo_addid_dep(Repo *repo, Offset olddeps, Id id, int isreq); extern Offset repo_reserve_ids(Repo *repo, Offset olddeps, int num); extern Offset repo_fix_legacy(Repo *repo, Offset provides, Offset supplements); -extern void pool_freeallrepos(Pool *pool); +extern void pool_freeallrepos(Pool *pool, int reuseids); static inline const char *repo_name(const Repo *repo) { diff --git a/src/repo_solv.c b/src/repo_solv.c index 25c64e4..1b0b595 100644 --- a/src/repo_solv.c +++ b/src/repo_solv.c @@ -499,16 +499,17 @@ repo_add_solv(Repo *repo, FILE *fp) idarraydataend = 0; } - if (repo->start && repo->start + repo->nsolvables != pool->nsolvables) - abort(); - if (!repo->start) - repo->start = pool->nsolvables; /* alloc space for our solvables */ - pool->solvables = (Solvable *)xrealloc(pool->solvables, (pool->nsolvables + numsolv) * sizeof(Solvable)); - if (numsolv) /* clear newly allocated area */ - memset(pool->solvables + pool->nsolvables, 0, numsolv * sizeof(Solvable)); + { + pool->solvables = (Solvable *)xrealloc(pool->solvables, (pool->nsolvables + numsolv) * sizeof(Solvable)); + + memset(pool->solvables + pool->nsolvables, 0, numsolv * sizeof(Solvable)); + if (!repo->start || repo->start == repo->end) + repo->start = pool->nsolvables; + repo->end = pool->nsolvables; + } /* * read solvables @@ -517,7 +518,7 @@ repo_add_solv(Repo *repo, FILE *fp) #if 0 printf("read solvables\n"); #endif - for (i = 0, s = pool->solvables + repo->start + repo->nsolvables; i < numsolv; i++, s++) + for (i = 0, s = pool->solvables + pool->nsolvables; i < numsolv; i++, s++) { s->repo = repo; databits = 0; @@ -613,6 +614,7 @@ repo_add_solv(Repo *repo, FILE *fp) xfree(idmap); xfree(solvdata); + repo->end += numsolv; repo->nsolvables += numsolv; pool->nsolvables += numsolv; } diff --git a/src/solver.c b/src/solver.c index 116f92b..1e8c005 100644 --- a/src/solver.c +++ b/src/solver.c @@ -40,16 +40,16 @@ solver_dep_installed(Solver *solv, Id dep) Reldep *rd = GETRELDEP(pool, dep); if (rd->flags == REL_AND) { - if (!dep_installed(solv, rd->name)) + if (!solver_dep_installed(solv, rd->name)) return 0; - return dep_installed(solv, rd->evr); + return solver_dep_installed(solv, rd->evr); } if (rd->flags == REL_NAMESPACE && rd->name == NAMESPACE_INSTALLED) - return dep_installed(solv, rd->evr); + return solver_dep_installed(solv, rd->evr); } FOR_PROVIDES(p, pp, dep) { - if (p >= solv->installed->start && p < solv->installed->start + solv->installed->nsolvables) + if (p == SYSTEMSOLVABLE || (solv->installed && pool->solvables[p].repo == solv->installed)) return 1; } #endif @@ -694,12 +694,13 @@ disableupdaterules(Solver *solv, Queue *job, int jobidx) { if (pool->solvables[p].name != s->name) continue; - if (p >= installed->start && p < installed->start + installed->nsolvables) + if (pool->solvables[p].repo == installed) MAPSET(&solv->noupdate, p - installed->start); } break; case SOLVER_ERASE_SOLVABLE: - if (what >= installed->start && what < installed->start + installed->nsolvables) + s = pool->solvables + what; + if (s->repo == installed) MAPSET(&solv->noupdate, what - installed->start); break; case SOLVER_ERASE_SOLVABLE_NAME: /* remove by capability */ @@ -708,7 +709,7 @@ disableupdaterules(Solver *solv, Queue *job, int jobidx) { if (how == SOLVER_ERASE_SOLVABLE_NAME && pool->solvables[p].name != what) continue; - if (p >= installed->start && p < installed->start + installed->nsolvables) + if (pool->solvables[p].repo == installed) MAPSET(&solv->noupdate, p - installed->start); } break; @@ -723,7 +724,7 @@ disableupdaterules(Solver *solv, Queue *job, int jobidx) if (jobidx != -1) { - /* re just disabled job #jobidx. enable all update rules + /* we just disabled job #jobidx. enable all update rules * that aren't disabled by the remaining job rules */ how = job->elements[jobidx]; what = job->elements[jobidx + 1]; @@ -735,17 +736,14 @@ disableupdaterules(Solver *solv, Queue *job, int jobidx) { if (pool->solvables[p].name != s->name) continue; - if (p < installed->start || p >= installed->start + installed->nsolvables) + if (pool->solvables[p].repo != installed) continue; if (MAPTST(&solv->noupdate, p - installed->start)) continue; r = solv->rules + solv->systemrules + (p - installed->start); if (r->w1) continue; - if (r->d == 0 || r->w2 != r->p) - r->w1 = r->p; - else - r->w1 = solv->pool->whatprovidesdata[r->d]; + enablerule(solv, r); if (pool->verbose) { printf("@@@ re-enabling "); @@ -754,17 +752,15 @@ disableupdaterules(Solver *solv, Queue *job, int jobidx) } break; case SOLVER_ERASE_SOLVABLE: - if (what < installed->start || what >= installed->start + installed->nsolvables) + s = pool->solvables + what; + if (s->repo != installed) break; if (MAPTST(&solv->noupdate, what - installed->start)) break; r = solv->rules + solv->systemrules + (what - installed->start); if (r->w1) break; - if (r->d == 0 || r->w2 != r->p) - r->w1 = r->p; - else - r->w1 = solv->pool->whatprovidesdata[r->d]; + enablerule(solv, r); if (pool->verbose) { printf("@@@ re-enabling "); @@ -777,17 +773,14 @@ disableupdaterules(Solver *solv, Queue *job, int jobidx) { if (how == SOLVER_ERASE_SOLVABLE_NAME && pool->solvables[p].name != what) continue; - if (p < installed->start || p >= installed->start + installed->nsolvables) + if (pool->solvables[p].repo != installed) continue; if (MAPTST(&solv->noupdate, p - installed->start)) continue; r = solv->rules + solv->systemrules + (p - installed->start); if (r->w1) continue; - if (r->d == 0 || r->w2 != r->p) - r->w1 = r->p; - else - r->w1 = solv->pool->whatprovidesdata[r->d]; + enablerule(solv, r); if (pool->verbose) { printf("@@@ re-enabling "); @@ -857,8 +850,7 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) dontfix = 0; if (installed /* Installed system available */ && !solv->fixsystem /* NOT repair errors in rpm dependency graph */ - && n >= installed->start /* is it installed? */ - && n < installed->start + installed->nsolvables) + && s->repo == installed) /* solvable is installed? */ { dontfix = 1; /* dont care about broken rpm deps */ } @@ -886,12 +878,12 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) * that are already broken. so if we find one provider * that was already installed, we know that the * dependency was not broken before so we enforce it */ - for (i = 0; dp[i]; i++) /* for all providers */ + for (i = 0; (p = dp[i]) != 0; i++) /* for all providers */ { - if (dp[i] >= installed->start && dp[i] < installed->start + installed->nsolvables) + if (pool->solvables[p].repo == installed) break; /* provider was installed */ } - if (!dp[i]) /* previously broken dependency */ + if (!p) /* previously broken dependency */ { if (pool->verbose) printf("ignoring broken requires %s of installed package %s-%s.%s\n", dep2str(pool, req), id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch)); @@ -945,7 +937,7 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) FOR_PROVIDES(p, pp, con) { /* dontfix: dont care about conflicts with already installed packs */ - if (dontfix && p >= installed->start && p < installed->start + installed->nsolvables) + if (dontfix && pool->solvables[p].repo == installed) continue; /* rule: -n|-p: either solvable _or_ provider of conflict */ addrule(solv, -n, -p); @@ -956,7 +948,7 @@ addrpmrulesforsolvable(Solver *solv, Solvable *s, Map *m) /*----------------------------------------- * check obsoletes if not installed */ - if (!installed || n < installed->start || n >= (installed->start + installed->nsolvables)) + if (!installed || pool->solvables[n].repo != installed) { /* not installed */ if (s->obsoletes) { @@ -1848,7 +1840,7 @@ solver_create(Pool *pool, Repo *installed) map_init(&solv->recommendsmap, pool->nsolvables); map_init(&solv->suggestsmap, pool->nsolvables); - map_init(&solv->noupdate, installed ? installed->nsolvables : 0); + map_init(&solv->noupdate, installed ? installed->end - installed->start : 0); solv->recommends_index = 0; solv->decisionmap = (Id *)xcalloc(pool->nsolvables, sizeof(Id)); @@ -1952,19 +1944,22 @@ run_solver(Solver *solv, int disablerules, int doweak) * installed packages */ - if (level < systemlevel && solv->installed->nsolvables) + if (level < systemlevel && solv->installed && solv->installed->nsolvables) { if (!solv->updatesystem) { /* try to keep as many packages as possible */ if (pool->verbose) printf("installing system packages\n"); - for (i = solv->installed->start, n = 0; ; i++, n++) + for (i = solv->installed->start, n = 0; ; i++) { if (n == solv->installed->nsolvables) break; - if (i == solv->installed->start + solv->installed->nsolvables) + if (i == solv->installed->end) i = solv->installed->start; s = pool->solvables + i; + if (s->repo != solv->installed) + continue; + n++; if (solv->decisionmap[i] != 0) continue; if (pool->verbose > 3) @@ -1983,10 +1978,10 @@ run_solver(Solver *solv, int disablerules, int doweak) if (solv->weaksystemrules) { if (pool->verbose) printf("installing weak system packages\n"); - for (i = solv->installed->start, n = 0; ; i++, n++) + for (i = solv->installed->start; i < solv->installed->end; i++) { - if (n == solv->installed->nsolvables) - break; + if (pool->solvables[i].repo != solv->installed) + continue; if (solv->decisionmap[i] > 0 || (solv->decisionmap[i] < 0 && solv->weaksystemrules[i - solv->installed->start] == 0)) continue; /* noupdate is set if a job is erasing the installed solvable or installing a specific version */ @@ -2019,12 +2014,9 @@ run_solver(Solver *solv, int disablerules, int doweak) return; } if (level <= olevel) - { - n = 0; - break; - } + break; } - if (n != solv->installed->nsolvables) + if (i < solv->installed->end) continue; } systemlevel = level; @@ -2497,58 +2489,62 @@ void printdecisions(Solver *solv) { Pool *pool = solv->pool; + Repo *installed = solv->installed; Id p, *obsoletesmap; int i; Solvable *s; obsoletesmap = (Id *)xcalloc(pool->nsolvables, sizeof(Id)); - for (i = 0; i < solv->decisionq.count; i++) + if (installed) { - Id *pp, n; + for (i = 0; i < solv->decisionq.count; i++) + { + Id *pp, n; - n = solv->decisionq.elements[i]; - if (n < 0) - continue; - if (n == SYSTEMSOLVABLE) - continue; - if (n >= solv->installed->start && n < solv->installed->start + solv->installed->nsolvables) - continue; - s = pool->solvables + n; - FOR_PROVIDES(p, pp, s->name) - if (s->name == pool->solvables[p].name) - { - if (p >= solv->installed->start && p < solv->installed->start + solv->installed->nsolvables && !obsoletesmap[p]) + n = solv->decisionq.elements[i]; + if (n < 0) + continue; + if (n == SYSTEMSOLVABLE) + continue; + s = pool->solvables + n; + if (s->repo == installed) /* obsoletes don't count for already installed packages */ + continue; + FOR_PROVIDES(p, pp, s->name) + if (s->name == pool->solvables[p].name) { - obsoletesmap[p] = n; - obsoletesmap[n]++; + if (pool->solvables[p].repo == installed && !obsoletesmap[p]) + { + obsoletesmap[p] = n; + obsoletesmap[n]++; + } } - } - } - for (i = 0; i < solv->decisionq.count; i++) - { - Id obs, *obsp; - Id *pp, n; + } + for (i = 0; i < solv->decisionq.count; i++) + { + Id obs, *obsp; + Id *pp, n; - n = solv->decisionq.elements[i]; - if (n < 0) - continue; - if (n == SYSTEMSOLVABLE) - continue; - if (n >= solv->installed->start && n < solv->installed->start + solv->installed->nsolvables) - continue; - s = pool->solvables + n; - if (!s->obsoletes) - continue; - obsp = s->repo->idarraydata + s->obsoletes; - while ((obs = *obsp++) != 0) - FOR_PROVIDES(p, pp, obs) - { - if (p >= solv->installed->start && p < solv->installed->start + solv->installed->nsolvables && !obsoletesmap[p]) + n = solv->decisionq.elements[i]; + if (n < 0) + continue; + if (n == SYSTEMSOLVABLE) + continue; + s = pool->solvables + n; + if (s->repo == installed) /* obsoletes don't count for already installed packages */ + continue; + if (!s->obsoletes) + continue; + obsp = s->repo->idarraydata + s->obsoletes; + while ((obs = *obsp++) != 0) + FOR_PROVIDES(p, pp, obs) { - obsoletesmap[p] = n; - obsoletesmap[n]++; + if (pool->solvables[p].repo == installed && !obsoletesmap[p]) + { + obsoletesmap[p] = n; + obsoletesmap[n]++; + } } - } + } } if (solv->rc_output) @@ -2558,20 +2554,25 @@ printdecisions(Solver *solv) /* print solvables to be erased */ - for (i = solv->installed->start; i < solv->installed->start + solv->installed->nsolvables; i++) + if (installed) { - if (solv->decisionmap[i] > 0) - continue; - if (obsoletesmap[i]) - continue; - s = pool->solvables + i; - if (solv->rc_output == 2) - printf(">!> remove %s-%s%s\n", id2str(pool, s->name), id2rc(solv, s->evr), id2str(pool, s->evr)); - else if (solv->rc_output) - printf(">!> remove %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch)); - else - printf("erase %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch)); - uninstalls++; + for (i = installed->start; i < installed->end; i++) + { + s = pool->solvables + i; + if (s->repo != installed) + continue; + if (solv->decisionmap[i] > 0) + continue; + if (obsoletesmap[i]) + continue; + if (solv->rc_output == 2) + printf(">!> remove %s-%s%s\n", id2str(pool, s->name), id2rc(solv, s->evr), id2str(pool, s->evr)); + else if (solv->rc_output) + printf(">!> remove %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch)); + else + printf("erase %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch)); + uninstalls++; + } } /* print solvables to be installed */ @@ -2584,9 +2585,9 @@ printdecisions(Solver *solv) continue; if (p == SYSTEMSOLVABLE) continue; - if (p >= solv->installed->start && p < solv->installed->start + solv->installed->nsolvables) - continue; s = pool->solvables + p; + if (installed && s->repo == installed) + continue; if (!obsoletesmap[p]) { @@ -2600,7 +2601,7 @@ printdecisions(Solver *solv) else if (!solv->rc_output) { printf("update %s-%s.%s (obsoletes", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch)); - for (j = solv->installed->start; j < solv->installed->start + solv->installed->nsolvables; j++) + for (j = installed->start; j < installed->end; j++) { if (obsoletesmap[j] != p) continue; @@ -2613,7 +2614,7 @@ printdecisions(Solver *solv) else { Solvable *f, *fn = 0; - for (j = solv->installed->start; j < solv->installed->start + solv->installed->nsolvables; j++) + for (j = installed->start; j < installed->end; j++) { if (obsoletesmap[j] != p) continue; @@ -2692,7 +2693,7 @@ printconflicts(Solver *solv, Solvable *s, Id pc) } } } - if (s->obsoletes && (!solv->installed || s - pool->solvables < solv->installed->start || s - pool->solvables >= solv->installed->start + solv->installed->nsolvables)) + if (s->obsoletes && (!solv->installed || s->repo != solv->installed)) { obsp = s->repo->idarraydata + s->obsoletes; while ((obs = *obsp++) != 0) @@ -2882,14 +2883,14 @@ printsolutions(Solver *solv, Queue *job) { case SOLVER_INSTALL_SOLVABLE: s = pool->solvables + what; - if (what >= solv->installed->start && what < solv->installed->start + solv->installed->nsolvables) + if (solv->installed && s->repo == solv->installed) printf("- do not keep %s-%s.%s installed\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch)); else printf("- do not install %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch)); break; case SOLVER_ERASE_SOLVABLE: s = pool->solvables + what; - if (what >= solv->installed->start && what < solv->installed->start + solv->installed->nsolvables) + if (solv->installed && s->repo == solv->installed) printf("- do not deinstall %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch)); else printf("- do not forbid installation of %s-%s.%s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch)); @@ -2971,11 +2972,15 @@ create_obsolete_index(Solver *solv) Id p, *pp, obs, *obsp, *obsoletes, *obsoletes_data; int i, n; + if (!installed || !installed->nsolvables) + return; /* create reverse obsoletes map for installed solvables */ - solv->obsoletes = obsoletes = xcalloc(installed->nsolvables, sizeof(Id)); + solv->obsoletes = obsoletes = xcalloc(installed->end - installed->start, sizeof(Id)); for (i = 1; i < pool->nsolvables; i++) { s = pool->solvables + i; + if (s->repo == installed) + continue; if (!s->obsoletes) continue; if (!pool_installable(pool, s)) @@ -2984,7 +2989,7 @@ create_obsolete_index(Solver *solv) while ((obs = *obsp++) != 0) FOR_PROVIDES(p, pp, obs) { - if (p < installed->start || p >= installed->start + installed->nsolvables) + if (pool->solvables[p].repo != installed) continue; if (pool->solvables[p].name == s->name) continue; @@ -3011,7 +3016,7 @@ create_obsolete_index(Solver *solv) while ((obs = *obsp++) != 0) FOR_PROVIDES(p, pp, obs) { - if (p < installed->start || p >= installed->start + installed->nsolvables) + if (pool->solvables[p].repo != installed) continue; if (pool->solvables[p].name == s->name) continue; @@ -3036,6 +3041,7 @@ void solve(Solver *solv, Queue *job) { Pool *pool = solv->pool; + Repo *installed = solv->installed; int i; Map addedmap; /* '1' == have rule for solvable */ Id how, what, p, *pp, d; @@ -3043,7 +3049,7 @@ solve(Solver *solv, Queue *job) Solvable *s; /* create obsolete index if needed */ - if (solv->noupdateprovide && solv->installed->nsolvables) + if (solv->noupdateprovide) create_obsolete_index(solv); /* @@ -3064,29 +3070,26 @@ solve(Solver *solv, Queue *job) solv->decisionmap[SYSTEMSOLVABLE] = 1; /* - * create rules for installed solvables -> keep them installed + * create rules for all package that could be involved with the solving * so called: rpm rules * */ - if (solv->pool->verbose > 3) - printf ("*** create rules for installed solvables -> keep them installed ***\n"); - for (i = solv->installed->start; i < solv->installed->start + solv->installed->nsolvables; i++) - addrpmrulesforsolvable(solv, pool->solvables + i, &addedmap); - - /* - * create install rules - * - * two passes, as we want to keep the rpm rules distinct from the job rules - * - */ + if (installed) + { + if (pool->verbose > 3) + printf ("*** create rules for installed solvables ***\n"); + for (i = installed->start, s = pool->solvables + i; i < installed->end; i++, s++) + if (s->repo == installed) + addrpmrulesforsolvable(solv, s, &addedmap); + if (pool->verbose > 3) + printf ("*** create rules for updaters of installed solvables ***\n"); + for (i = installed->start, s = pool->solvables + i; i < installed->end; i++, s++) + if (s->repo == installed) + addrpmrulesforupdaters(solv, s, &addedmap, 1); + } - /* - * solvable rules - * process job rules for solvables - */ if (solv->pool->verbose > 3) - printf ("*** create install rules ***\n"); - + printf ("*** create rpm rules for packages involved with a job ***\n"); for (i = 0; i < job->count; i += 2) { how = job->elements[i]; @@ -3114,9 +3117,8 @@ solve(Solver *solv, Queue *job) } } - for (i = solv->installed->start; i < solv->installed->start + solv->installed->nsolvables; i++) - addrpmrulesforupdaters(solv, pool->solvables + i, &addedmap, 1); - + if (solv->pool->verbose > 3) + printf ("*** create rpm rules for recommended/suggested packages ***\n"); if (solv->pool->verbose > 3) printf ("*** Add rules for week dependencies ***\n"); @@ -3134,7 +3136,7 @@ solve(Solver *solv, Queue *job) if (MAPTST(&addedmap, i)) possible++; } - printf("%d of %d installable solvables used for solving\n", possible, installable); + printf("%d of %d installable solvables considered for solving\n", possible, installable); } #endif @@ -3255,28 +3257,32 @@ solve(Solver *solv, Queue *job) * */ - if (!solv->allowuninstall) + if (installed && !solv->allowuninstall) { /* loop over all installed solvables */ /* we create all update rules, but disable some later on depending on the job */ - for (i = solv->installed->start; i < solv->installed->start + solv->installed->nsolvables; i++) - addupdaterule(solv, pool->solvables + i, 0); + for (i = installed->start, s = pool->solvables + i; i < installed->end; i++, s++) + if (s->repo == installed) + addupdaterule(solv, s, 0); + else + addupdaterule(solv, 0, 0); /* create dummy rule */ /* consistency check: we added a rule for _every_ system solvable */ - if (solv->nrules - solv->systemrules != solv->installed->nsolvables) + if (solv->nrules - solv->systemrules != installed->end - installed->start) abort(); } /* create special weak system rules */ /* those are used later on to keep a version of the installed packages in best effort mode */ - if (solv->installed->nsolvables) + if (installed && installed->nsolvables) { - solv->weaksystemrules = xcalloc(solv->installed->nsolvables, sizeof(Id)); - for (i = 0; i < solv->installed->nsolvables; i++) - { - policy_findupdatepackages(solv, pool->solvables + solv->installed->start + i, &q, 1); - if (q.count) - solv->weaksystemrules[i] = pool_queuetowhatprovides(pool, &q); - } + solv->weaksystemrules = xcalloc(installed->end - installed->start, sizeof(Id)); + for (i = installed->start, s = pool->solvables + i; i < installed->end; i++, s++) + if (s->repo == installed) + { + policy_findupdatepackages(solv, s, &q, 1); + if (q.count) + solv->weaksystemrules[i - installed->start] = pool_queuetowhatprovides(pool, &q); + } } /* free unneeded memory */ @@ -3288,15 +3294,16 @@ solve(Solver *solv, Queue *job) /* try real hard to keep packages installed */ if (0) { - for (i = 0; i < solv->installed->nsolvables; i++) - { - /* FIXME: can't work with refine_suggestion! */ - /* need to always add the rule but disable it */ - if (MAPTST(&solv->noupdate, i)) - continue; - d = solv->weaksystemrules[i]; - addrule(solv, solv->installed->start + i, d); - } + for (i = installed->start, s = pool->solvables + i; i < installed->end; i++, s++) + if (s->repo == installed) + { + /* FIXME: can't work with refine_suggestion! */ + /* need to always add the rule but disable it */ + if (MAPTST(&solv->noupdate, i - installed->start)) + continue; + d = solv->weaksystemrules[i - installed->start]; + addrule(solv, i, d); + } } /* diff --git a/tools/dumpsolv.c b/tools/dumpsolv.c index 64a02f4..4fe151b 100644 --- a/tools/dumpsolv.c +++ b/tools/dumpsolv.c @@ -45,9 +45,11 @@ int main(int argc, char **argv) repo = repo_create(pool, argc != 1 ? argv[1] : ""); repo_add_solv(repo, stdin); printf("repo contains %d solvables\n", repo->nsolvables); - for (i = repo->start; i < repo->start + repo->nsolvables; i++) + for (i = repo->start; i < repo->end; i++) { s = pool->solvables + i; + if (s->repo != repo) + continue; printf("\n"); printf("solvable %d:\n", i); printf("name: %s %s %s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch)); diff --git a/tools/mergesolv.c b/tools/mergesolv.c index 1c0b629..13561e1 100644 --- a/tools/mergesolv.c +++ b/tools/mergesolv.c @@ -90,7 +90,7 @@ main(int argc, char **argv) } while (pool->nrepos > 1) { - repo_free(pool->repos[1]); + repo_free(pool->repos[pool->nrepos - 1], 1); } free (pool->repos[0]->idarraydata); pool->repos[0]->idarraydata = new_id; diff --git a/tools/repo_content.c b/tools/repo_content.c index bd35db8..7684e82 100644 --- a/tools/repo_content.c +++ b/tools/repo_content.c @@ -179,6 +179,10 @@ repo_add_content(Repo *repo, FILE *fp) pack = 0; s = 0; + if (!repo->start || repo->start == repo->end) + repo->start = pool->nsolvables; + repo->end = pool->nsolvables; + for (;;) { char *fields[2]; @@ -276,6 +280,7 @@ repo_add_content(Repo *repo, FILE *fp) pool->nsolvables += pack; repo->nsolvables += pack; + repo->end += pack; if (pd.tmp) free(pd.tmp); free(line); diff --git a/tools/repo_helix.c b/tools/repo_helix.c index 0f2fdb2..6e2431e 100644 --- a/tools/repo_helix.c +++ b/tools/repo_helix.c @@ -828,8 +828,9 @@ repo_add_helix(Repo *repo, FILE *fp) if (repo->start && repo->start + repo->nsolvables != pool->nsolvables) abort(); - if (!repo->start) + if (!repo->start || repo->start == repo->end) repo->start = pool->nsolvables; + repo->end = pool->nsolvables; /* prepare parsedata */ memset(&pd, 0, sizeof(pd)); @@ -875,6 +876,7 @@ repo_add_helix(Repo *repo, FILE *fp) // adapt package count pool->nsolvables += pd.pack; repo->nsolvables += pd.pack; + repo->end += pd.pack; free(pd.content); free(pd.evrspace); diff --git a/tools/repo_patchxml.c b/tools/repo_patchxml.c index b50a781..f9a06f1 100644 --- a/tools/repo_patchxml.c +++ b/tools/repo_patchxml.c @@ -454,8 +454,9 @@ repo_add_patchxml(Repo *repo, FILE *fp) if (repo->start && repo->start + repo->nsolvables != pool->nsolvables) abort(); - if (!repo->start) + if (!repo->start || repo->start == repo->end) repo->start = pool->nsolvables; + repo->end = pool->nsolvables; memset(&pd, 0, sizeof(pd)); for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++) @@ -488,6 +489,7 @@ repo_add_patchxml(Repo *repo, FILE *fp) pool->nsolvables += pd.pack; repo->nsolvables += pd.pack; + repo->end += pd.pack; free(pd.content); } diff --git a/tools/repo_rpmdb.c b/tools/repo_rpmdb.c index c947250..0b929fd 100644 --- a/tools/repo_rpmdb.c +++ b/tools/repo_rpmdb.c @@ -531,8 +531,11 @@ repo_add_rpmdb(Repo *repo, Repo *ref) if (repo->start && repo->start + repo->nsolvables != pool->nsolvables) abort(); - if (!repo->start) + if (!repo->start || repo->start == repo->end) repo->start = pool->nsolvables; + repo->end = pool->nsolvables; + if (repo->start != repo->end) + abort(); /* FIXME: rpmdbid */ if (ref && !(ref->nsolvables && ref->rpmdbid)) ref = 0; @@ -816,6 +819,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref) free(rpmhead); pool->nsolvables += nrpmids; repo->nsolvables += nrpmids; + repo->end += nrpmids; if (db) db->close(db, 0); diff --git a/tools/repo_rpmmd.c b/tools/repo_rpmmd.c index c1e33d4..9cefc2d 100644 --- a/tools/repo_rpmmd.c +++ b/tools/repo_rpmmd.c @@ -433,10 +433,9 @@ repo_add_rpmmd(Repo *repo, FILE *fp) int i, l; struct stateswitch *sw; - if (repo->start && repo->start + repo->nsolvables != pool->nsolvables) - abort(); - if (!repo->start) + if (!repo->start || repo->start == repo->end) repo->start = pool->nsolvables; + repo->end = pool->nsolvables; memset(&pd, 0, sizeof(pd)); for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++) @@ -469,6 +468,7 @@ repo_add_rpmmd(Repo *repo, FILE *fp) pool->nsolvables += pd.pack; repo->nsolvables += pd.pack; + repo->end += pd.pack; free(pd.content); } diff --git a/tools/repo_susetags.c b/tools/repo_susetags.c index 182b6ee..2fdcba8 100644 --- a/tools/repo_susetags.c +++ b/tools/repo_susetags.c @@ -151,10 +151,9 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr) char *sp[5]; struct parsedata pd; - if (repo->start && repo->start + repo->nsolvables != pool->nsolvables) - abort(); - if (!repo->start) + if (!repo->start || repo->start == repo->end) repo->start = pool->nsolvables; + repo->end = pool->nsolvables; attr = new_store (pool); memset(&pd, 0, sizeof(pd)); @@ -430,6 +429,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, int with_attr) pool->nsolvables += pack; repo->nsolvables += pack; + repo->end += pack; if (pd.tmp) free(pd.tmp); free(line); diff --git a/tools/repo_write.c b/tools/repo_write.c index b66fd20..28d88e6 100644 --- a/tools/repo_write.c +++ b/tools/repo_write.c @@ -193,7 +193,7 @@ repo_write(Repo *repo, FILE *fp) { Pool *pool = repo->pool; int i, numsolvdata; - Solvable *s, *sstart; + Solvable *s; NeedId *needid; int nstrings, nrels; unsigned int sizeid; @@ -204,17 +204,18 @@ repo_write(Repo *repo, FILE *fp) int bits, bitmaps; int nsolvables; - nsolvables = repo->nsolvables; - sstart = pool->solvables + repo->start; + nsolvables = 0; idarraydata = repo->idarraydata; needid = (NeedId *)calloc(pool->nstrings + pool->nrels, sizeof(*needid)); memset(idsizes, 0, sizeof(idsizes)); - for (i = 0; i < nsolvables; i++) + for (i = repo->start, s = pool->solvables + i; i < repo->end; i++, s++) { - s = sstart + i; + if (s->repo != repo) + continue; + nsolvables++; needid[s->name].need++; needid[s->arch].need++; needid[s->evr].need++; @@ -242,6 +243,8 @@ repo_write(Repo *repo, FILE *fp) if (s->freshens) idsizes[SOLVABLE_FRESHENS] += incneedid(pool, idarraydata + s->freshens, needid); } + if (nsolvables != repo->nsolvables) + abort(); idsizes[SOLVABLE_NAME] = 1; idsizes[SOLVABLE_ARCH] = 1; @@ -364,9 +367,10 @@ repo_write(Repo *repo, FILE *fp) write_u32(fp, 0); } - for (i = 0; i < nsolvables; ++i) + for (i = repo->start, s = pool->solvables + i; i < repo->end; i++, s++) { - s = sstart + i; + if (s->repo != repo) + continue; bits = 0; if (idsizes[SOLVABLE_FRESHENS]) bits = (bits << 1) | (s->freshens ? 1 : 0); diff --git a/tools/rpmdb2solv.c b/tools/rpmdb2solv.c index d8adfae..8ce42cb 100644 --- a/tools/rpmdb2solv.c +++ b/tools/rpmdb2solv.c @@ -49,7 +49,7 @@ main(int argc, char **argv) if (ref->pool != pool) pool_free(ref->pool); else - repo_free(ref); + repo_free(ref, 1); ref = 0; } -- 2.7.4