Dataiterator can walk over multiple repos now (SEARCH_ALL_REPOS flag).
authorMichael Matz <matz@suse.de>
Thu, 3 Apr 2008 20:10:27 +0000 (20:10 +0000)
committerMichael Matz <matz@suse.de>
Thu, 3 Apr 2008 20:10:27 +0000 (20:10 +0000)
Add some functions for skipping various entities while iterating, or
directly jumping to a solvable or repo.

src/repo.h
src/repodata.c

index 07dc687..60d1891 100644 (file)
@@ -157,6 +157,7 @@ typedef struct _KeyValue {
 #define        SEARCH_NOCASE                   (1<<8)
 #define        SEARCH_NO_STORAGE_SOLVABLE      (1<<9)
 #define SEARCH_EXTRA                   (1<<10)
+#define SEARCH_ALL_REPOS               (1<<11)
 
 /* Internal */
 #define __SEARCH_ONESOLVABLE           (1 << 31)
@@ -197,6 +198,11 @@ typedef struct _Dataiterator
 void dataiterator_init(Dataiterator *di, Repo *repo, Id p, Id keyname,
                       const char *match, int flags);
 int dataiterator_step(Dataiterator *di);
+void dataiterator_skip_attribute(Dataiterator *di);
+void dataiterator_skip_solvable(Dataiterator *di);
+void dataiterator_skip_repo(Dataiterator *di);
+void dataiterator_jump_to_solvable(Dataiterator *di, Solvable *s);
+void dataiterator_jump_to_repo(Dataiterator *di, Repo *repo);
 
 void repo_set_id(Repo *repo, Id p, Id keyname, Id id);
 void repo_set_num(Repo *repo, Id p, Id keyname, Id num);
index 379eb88..c4b8156 100644 (file)
@@ -797,21 +797,25 @@ restart:
                if (!s->name)
                  continue;
                di->kv.id = s->name;
+               di->kv.eof = 1;
                break;
              case SOLVABLE_ARCH:
                if (!s->arch)
                  continue;
                di->kv.id = s->arch;
+               di->kv.eof = 1;
                break;
              case SOLVABLE_EVR:
                if (!s->evr)
                  continue;
                di->kv.id = s->evr;
+               di->kv.eof = 1;
                break;
              case SOLVABLE_VENDOR:
                if (!s->vendor)
                  continue;
                di->kv.id = s->vendor;
+               di->kv.eof = 1;
                break;
              case SOLVABLE_PROVIDES:
                di->idp = s->provides
@@ -853,6 +857,7 @@ restart:
                if (!di->repo->rpmdbid)
                  continue;
                di->kv.num = di->repo->rpmdbid[di->solvid - di->repo->start];
+               di->kv.eof = 1;
                break;
              default:
                di->data = di->repo->repodata - 1;
@@ -889,17 +894,30 @@ restart:
                              if (di->solvid >= repo->end)
                                {
                                  if (!(di->flags & SEARCH_EXTRA))
-                                   return 0;
+                                   goto skiprepo;
                                  di->solvid = -1;
                                  if (di->solvid < -repo->nextra)
-                                   return 0;
+                                   goto skiprepo;
                                }
                            }
                          else
                            {
                              --di->solvid;
                              if (di->solvid < -repo->nextra)
-                               return 0;
+                               {
+skiprepo:;
+                                 Pool *pool = di->repo->pool;
+                                 if (!(di->flags & SEARCH_ALL_REPOS)
+                                     || di->repo == pool->repos[pool->nrepos - 1])
+                                   return 0;
+                                 int i;
+                                 for (i = 0; i < pool->nrepos; i++)
+                                   if (di->repo == pool->repos[i])
+                                     break;
+                                 di->repo = pool->repos[i + 1];
+                                 dataiterator_init(di, di->repo, 0, di->keyname, di->match, di->flags);
+                                 continue;
+                               }
                            }
                          di->data = repo->repodata - 1;
                          if (di->solvid < 0
@@ -935,6 +953,56 @@ weg2:
   return 1;
 }
 
+void
+dataiterator_skip_attribute(Dataiterator *di)
+{
+  if (di->state)
+    di->idp = 0;
+  /* This will make the next _step call to retrieve the next field.  */
+  di->kv.eof = 1;
+}
+
+void
+dataiterator_skip_solvable(Dataiterator *di)
+{
+  /* We're done with this field.  */
+  di->kv.eof = 1;
+  /* And with solvable data.  */
+  di->state = 0;
+  /* And with all keys for this repodata and thing. */
+  static Id zeroid = 0;
+  di->keyp = &zeroid;
+  /* And with all repodatas for this thing.  */
+  di->data = di->repo->repodata + di->repo->nrepodata - 1;
+  /* Hence the next call to _step will retrieve the next thing.  */
+}
+
+void
+dataiterator_skip_repo(Dataiterator *di)
+{
+  dataiterator_skip_solvable(di);
+  /* We're done with all solvables and all extra things for this repo.  */
+  di->solvid = -1 - di->repo->nextra;
+}
+
+void
+dataiterator_jump_to_solvable(Dataiterator *di, Solvable *s)
+{
+  di->repo = s->repo;
+  /* Simulate us being done with the solvable before the requested one.  */
+  dataiterator_skip_solvable(di);
+  di->solvid = s - s->repo->pool->solvables;
+  di->solvid--;
+}
+
+void
+dataiterator_jump_to_repo(Dataiterator *di, Repo *repo)
+{
+  di->repo = repo;
+  dataiterator_skip_solvable(di);
+  di->solvid = repo->start - 1;
+}
+
 /* extend repodata so that it includes solvables p */
 void
 repodata_extend(Repodata *data, Id p)