summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Schroeder <mls@suse.de>2012-10-26 14:42:13 +0200
committerMichael Schroeder <mls@suse.de>2012-10-26 14:42:13 +0200
commit68c7ba0920556da5d97315f8077b8d996236d0ba (patch)
treeb526735653d56ed7ba5decb4b7b92fb1b916ad3f
parente4baafbc3b96a10cecd36571a865b9fe538db2b7 (diff)
downloadlibsolv-68c7ba0920556da5d97315f8077b8d996236d0ba.tar.gz
libsolv-68c7ba0920556da5d97315f8077b8d996236d0ba.tar.bz2
libsolv-68c7ba0920556da5d97315f8077b8d996236d0ba.zip
add pool_job2solvables and selection_solvables
-rw-r--r--bindings/solv.i32
-rw-r--r--examples/solv.c11
-rw-r--r--src/libsolv.ver2
-rw-r--r--src/repo.h4
-rw-r--r--src/selection.c60
-rw-r--r--src/selection.h1
-rw-r--r--src/solver.c28
-rw-r--r--src/solver.h12
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
}