add pool_job2solvables and selection_solvables
authorMichael Schroeder <mls@suse.de>
Fri, 26 Oct 2012 12:42:13 +0000 (14:42 +0200)
committerMichael Schroeder <mls@suse.de>
Fri, 26 Oct 2012 12:42:13 +0000 (14:42 +0200)
bindings/solv.i
examples/solv.c
src/libsolv.ver
src/repo.h
src/selection.c
src/selection.h
src/solver.c
src/solver.h

index 5bef32b..12df242 100644 (file)
@@ -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
index 42791ac..a40e6d0 100644 (file)
@@ -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);
index d5f2d5e..1ad371a 100644 (file)
@@ -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;
index 8e5078d..d839157 100644 (file)
@@ -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)        \
index 2a86910..4ad9cc7 100644 (file)
@@ -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)
     {
index 62eb37d..2966b99 100644 (file)
@@ -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
index 68ff49f..a284017 100644 (file)
@@ -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);
+    }
+}
+
index 46be845..1f04c1d 100644 (file)
@@ -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
 }