From 68c7ba0920556da5d97315f8077b8d996236d0ba Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Fri, 26 Oct 2012 14:42:13 +0200 Subject: [PATCH] add pool_job2solvables and selection_solvables --- bindings/solv.i | 32 ++++++++++-------------------- examples/solv.c | 11 ++++++++--- src/libsolv.ver | 2 ++ src/repo.h | 4 +++- src/selection.c | 60 +++++++++++++++++++++++++++++++++++---------------------- src/selection.h | 1 + src/solver.c | 28 +++++++++++++++++++++++++++ src/solver.h | 12 ++++++++++-- 8 files changed, 99 insertions(+), 51 deletions(-) diff --git a/bindings/solv.i b/bindings/solv.i index 5bef32b..12df242 100644 --- a/bindings/solv.i +++ b/bindings/solv.i @@ -688,30 +688,9 @@ typedef struct { %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id)); %newobject solvables; Queue solvables() { - Pool *pool = $self->pool; - Id p, pp, how; Queue q; queue_init(&q); - how = $self->how & SOLVER_SELECTMASK; - if (how == SOLVER_SOLVABLE_ALL) - { - for (p = 2; p < pool->nsolvables; p++) - if (pool->solvables[p].repo) - queue_push(&q, p); - } - else if (how == SOLVER_SOLVABLE_REPO) - { - Repo *repo = pool_id2repo(pool, $self->what); - Solvable *s; - if (repo) - FOR_REPO_SOLVABLES(repo, p, s) - queue_push(&q, p); - } - else - { - FOR_JOB_SELECT(p, pp, how, $self->what) - queue_push(&q, p); - } + pool_job2solvables($self->pool, &q, $self->how, $self->what); return q; } @@ -792,6 +771,15 @@ typedef struct { return q; } + %typemap(out) Queue solvables Queue2Array(XSolvable *, 1, new_XSolvable(arg1->pool, id)); + %newobject solvables; + Queue solvables() { + Queue q; + queue_init(&q); + selection_solvables($self->pool, &q, &$self->q); + return q; + } + #if defined(SWIGPERL) %rename("str") __str__; #endif diff --git a/examples/solv.c b/examples/solv.c index 42791ac..a40e6d0 100644 --- a/examples/solv.c +++ b/examples/solv.c @@ -2718,12 +2718,16 @@ main(int argc, char **argv) if (mainmode == MODE_LIST || mainmode == MODE_INFO) { /* list mode, no solver needed */ + Queue q; + queue_init(&q); for (i = 0; i < job.count; i += 2) { - Id how = job.elements[i] & SOLVER_SELECTMASK; - FOR_JOB_SELECT(p, pp, how, job.elements[i + 1]) + int j; + queue_empty(&q); + pool_job2solvables(pool, &q, job.elements[i], job.elements[i + 1]); + for (j = 0; j < q.count; j++) { - Solvable *s = pool_id2solvable(pool, p); + Solvable *s = pool_id2solvable(pool, q.elements[j]); if (mainmode == MODE_INFO) { const char *str; @@ -2752,6 +2756,7 @@ main(int argc, char **argv) } } } + queue_free(&q); queue_free(&job); pool_free(pool); free_repoinfos(repoinfos, nrepoinfos); diff --git a/src/libsolv.ver b/src/libsolv.ver index d5f2d5e..1ad371a 100644 --- a/src/libsolv.ver +++ b/src/libsolv.ver @@ -71,6 +71,7 @@ SOLV_1.0 { pool_id2langid; pool_id2rel; pool_id2str; + pool_job2solvables; pool_job2str; pool_lookup_bin_checksum; pool_lookup_checksum; @@ -224,6 +225,7 @@ SOLV_1.0 { selection_add; selection_limit; selection_make; + selection_solvables; solv_bin2hex; solv_calloc; solv_chksum_add; diff --git a/src/repo.h b/src/repo.h index 8e5078d..d839157 100644 --- a/src/repo.h +++ b/src/repo.h @@ -149,7 +149,9 @@ void repo_disable_paging(Repo *repo); /* iterator macros */ #define FOR_REPO_SOLVABLES(r, p, s) \ for (p = (r)->start, s = (r)->pool->solvables + p; p < (r)->end; p++, s = (r)->pool->solvables + p) \ - if (s->repo == (r)) + if (s->repo != (r)) \ + continue; \ + else #ifdef LIBSOLV_INTERNAL #define FOR_REPODATAS(repo, rdid, data) \ diff --git a/src/selection.c b/src/selection.c index 2a86910..4ad9cc7 100644 --- a/src/selection.c +++ b/src/selection.c @@ -71,29 +71,25 @@ selection_prune(Pool *pool, Queue *selection) static int -selection_flatten_sortcmp(const void *ap, const void *bp, void *dp) +selection_solvables_sortcmp(const void *ap, const void *bp, void *dp) { return *(const Id *)ap - *(const Id *)bp; } -static void -selection_flatten(Pool *pool, Queue *selection) +void +selection_solvables(Pool *pool, Queue *selection, Queue *pkgs) { - Queue q; int i, j; Id p, pp, lastid; - if (selection->count <= 1) - return; - queue_init(&q); + queue_empty(pkgs); for (i = 0; i < selection->count; i += 2) { Id select = selection->elements[i] & SOLVER_SELECTMASK; if (select == SOLVER_SOLVABLE_ALL) { - selection->elements[0] = selection->elements[i]; - selection->elements[1] = selection->elements[i + 1]; - queue_truncate(selection, 2); - return; + for (p = 2; p < pool->nsolvables; p++) + if (pool->solvables[p].repo) + queue_push(pkgs, p); } if (select == SOLVER_SOLVABLE_REPO) { @@ -101,29 +97,47 @@ selection_flatten(Pool *pool, Queue *selection) Repo *repo = pool_id2repo(pool, selection->elements[i + 1]); if (repo) FOR_REPO_SOLVABLES(repo, p, s) - queue_push(&q, p); + queue_push(pkgs, p); } else { FOR_JOB_SELECT(p, pp, select, selection->elements[i + 1]) - queue_push(&q, p); + queue_push(pkgs, p); } } + if (pkgs->count < 2) + return; + /* sort and unify */ + solv_sort(pkgs->elements, pkgs->count, sizeof(Id), selection_solvables_sortcmp, NULL); + lastid = pkgs->elements[0]; + for (i = j = 1; i < pkgs->count; i++) + if (pkgs->elements[i] != lastid) + pkgs->elements[j++] = lastid = pkgs->elements[i]; + queue_truncate(pkgs, j); +} + +static void +selection_flatten(Pool *pool, Queue *selection) +{ + Queue q; + int i; + if (selection->count <= 1) + return; + for (i = 0; i < selection->count; i += 2) + if ((selection->elements[i] & SOLVER_SELECTMASK) == SOLVER_SOLVABLE_ALL) + { + selection->elements[0] = selection->elements[i]; + selection->elements[1] = selection->elements[i + 1]; + queue_truncate(selection, 2); + return; + } + queue_init(&q); + selection_solvables(pool, selection, &q); if (!q.count) { queue_empty(selection); return; } - if (q.count > 1) - { - /* sort and unify */ - solv_sort(q.elements, q.count, sizeof(Id), selection_flatten_sortcmp, NULL); - lastid = q.elements[0]; - for (i = j = 1; i < q.count; i++) - if (q.elements[i] != lastid) - q.elements[j++] = lastid = q.elements[i]; - queue_truncate(&q, j); - } queue_truncate(selection, 2); if (q.count > 1) { diff --git a/src/selection.h b/src/selection.h index 62eb37d..2966b99 100644 --- a/src/selection.h +++ b/src/selection.h @@ -27,5 +27,6 @@ extern int selection_make(Pool *pool, Queue *selection, const char *name, int flags); extern void selection_limit(Pool *pool, Queue *sel1, Queue *sel2); extern void selection_add(Pool *pool, Queue *sel1, Queue *sel2); +extern void selection_solvables(Pool *pool, Queue *selection, Queue *pkgs); #endif diff --git a/src/solver.c b/src/solver.c index 68ff49f..a284017 100644 --- a/src/solver.c +++ b/src/solver.c @@ -3591,3 +3591,31 @@ solver_describe_weakdep_decision(Solver *solv, Id p, Queue *whyq) } } } + +void +pool_job2solvables(Pool *pool, Queue *pkgs, Id how, Id what) +{ + Id p, pp; + how &= SOLVER_SELECTMASK; + queue_empty(pkgs); + if (how == SOLVER_SOLVABLE_ALL) + { + for (p = 2; p < pool->nsolvables; p++) + if (pool->solvables[p].repo) + queue_push(pkgs, p); + } + else if (how == SOLVER_SOLVABLE_REPO) + { + Repo *repo = pool_id2repo(pool, what); + Solvable *s; + if (repo) + FOR_REPO_SOLVABLES(repo, p, s) + queue_push(pkgs, p); + } + else + { + FOR_JOB_SELECT(p, pp, how, what) + queue_push(pkgs, p); + } +} + diff --git a/src/solver.h b/src/solver.h index 46be845..1f04c1d 100644 --- a/src/solver.h +++ b/src/solver.h @@ -325,6 +325,7 @@ void solver_calc_duchanges(Solver *solv, DUChanges *mps, int nmps); int solver_calc_installsizechange(Solver *solv); void solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res); +void pool_job2solvables(Pool *pool, Queue *pkgs, Id how, Id what); /* iterate over all literals of a rule */ /* WARNING: loop body must not relocate whatprovidesdata, e.g. by @@ -334,6 +335,9 @@ void solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res); dp = !l ? &r->w2 : pool->whatprovidesdata + l, \ l = r->p; l; l = (dp != &r->w2 + 1 ? *dp++ : 0)) +/* XXX: this currently doesn't work correctly for SOLVER_SOLVABLE_REPO and + SOLVER_SOLVABLE_ALL */ + /* iterate over all packages selected by a job */ #define FOR_JOB_SELECT(p, pp, select, what) \ if (select == SOLVER_SOLVABLE_REPO || select == SOLVER_SOLVABLE_ALL) \ @@ -341,8 +345,12 @@ void solver_trivial_installable(Solver *solv, Queue *pkgs, Queue *res); else for (pp = (select == SOLVER_SOLVABLE ? 0 : \ select == SOLVER_SOLVABLE_ONE_OF ? what : \ pool_whatprovides(pool, what)), \ - 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)) + 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) == 0) \ + continue; \ + else #ifdef __cplusplus } -- 2.7.4