- hide repodata internals (needed to move repo_write from ext to src for this)
authorMichael Schroeder <mls@suse.de>
Fri, 17 Feb 2012 14:47:47 +0000 (15:47 +0100)
committerMichael Schroeder <mls@suse.de>
Fri, 17 Feb 2012 14:47:47 +0000 (15:47 +0100)
also deleted repodata_create, use repo_add_repodata instead

18 files changed:
bindings/solv.i
examples/solv.c
ext/CMakeLists.txt
ext/libsolvext.ver
ext/repo_helix.c
ext/repo_rpmdb.c
ext/repo_rpmmd.c
ext/repo_susetags.c
src/CMakeLists.txt
src/libsolv.ver
src/pool.h
src/repo.c
src/repo.h
src/repo_solv.c
src/repo_write.c [moved from ext/repo_write.c with 99% similarity]
src/repo_write.h [moved from ext/repo_write.h with 100% similarity]
src/repodata.c
src/repodata.h

index a1d9d5b..7b75536 100644 (file)
@@ -808,7 +808,7 @@ typedef struct {
 #if defined(SWIGPYTHON)
   %{
   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
-    XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
+    XRepodata *xd = new_XRepodata(data->repo, data->repodataid);
     PyObject *args = Py_BuildValue("(O)", SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_POINTER_OWN | 0));
     PyObject *result = PyEval_CallObject((PyObject *)d, args);
     int ecode = 0;
@@ -837,7 +837,7 @@ typedef struct {
     int count;
     int ret = 0;
     dSP;
-    XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
+    XRepodata *xd = new_XRepodata(data->repo, data->repodataid);
 
     ENTER;
     SAVETMPS;
@@ -866,7 +866,7 @@ typedef struct {
 #if defined(SWIGRUBY)
 %{
   SWIGINTERN int loadcallback(Pool *pool, Repodata *data, void *d) {
-    XRepodata *xd = new_XRepodata(data->repo, data - data->repo->repodata);
+    XRepodata *xd = new_XRepodata(data->repo, data->repodataid);
     VALUE callable = (VALUE)d;
     VALUE rd = SWIG_NewPointerObj(SWIG_as_voidptr(xd), SWIGTYPE_p_XRepodata, SWIG_POINTER_OWN | 0);
     VALUE res = rb_funcall(callable, rb_intern("call"), 1, rd);
@@ -1198,14 +1198,14 @@ typedef struct {
 
   XRepodata *add_repodata(int flags = 0) {
     Repodata *rd = repo_add_repodata($self, flags);
-    return new_XRepodata($self, rd - $self->repodata);
+    return new_XRepodata($self, rd->repodataid);
   }
 
   void create_stubs() {
     Repodata *data;
     if (!$self->nrepodata)
       return;
-    data = $self->repodata  + ($self->nrepodata - 1);
+    data = repo_id2repodata($self, $self->nrepodata - 1);
     if (data->state != REPODATA_STUB)
       repodata_create_stubs(data);
   }
@@ -1220,17 +1220,22 @@ typedef struct {
     return 1;
   }
   XRepodata *first_repodata() {
-     int i;
-     if ($self->nrepodata < 2)
+    Repodata *data;
+    int i;
+    if ($self->nrepodata < 2)
+      return 0;
+    /* make sure all repodatas but the first are extensions */
+    data = repo_id2repodata($self, 1);
+    if (data->loadcallback)
        return 0;
-     /* make sure all repodatas but the first are extensions */
-     if ($self->repodata[1].loadcallback)
-        return 0;
-     for (i = 2; i < $self->nrepodata; i++)
-       if (!$self->repodata[i].loadcallback)
-         return 0;       /* oops, not an extension */
-     return new_XRepodata($self, 1);
-   }
+    for (i = 2; i < $self->nrepodata; i++)
+      {
+        data = repo_id2repodata($self, i);
+        if (!data->loadcallback)
+          return 0;       /* oops, not an extension */
+      }
+    return new_XRepodata($self, 1);
+  }
 
   bool __eq__(Repo *repo) {
     return $self == repo;
@@ -2383,54 +2388,54 @@ rb_eval_string(
     return xr;
   }
   Id new_handle() {
-    return repodata_new_handle($self->repo->repodata + $self->id);
+    return repodata_new_handle(repo_id2repodata($self->repo, $self->id));
   }
   void set_id(Id solvid, Id keyname, Id id) {
-    repodata_set_id($self->repo->repodata + $self->id, solvid, keyname, id);
+    repodata_set_id(repo_id2repodata($self->repo, $self->id), solvid, keyname, id);
   }
   void set_str(Id solvid, Id keyname, const char *str) {
-    repodata_set_str($self->repo->repodata + $self->id, solvid, keyname, str);
+    repodata_set_str(repo_id2repodata($self->repo, $self->id), solvid, keyname, str);
   }
   void set_poolstr(Id solvid, Id keyname, const char *str) {
-    repodata_set_poolstr($self->repo->repodata + $self->id, solvid, keyname, str);
+    repodata_set_poolstr(repo_id2repodata($self->repo, $self->id), solvid, keyname, str);
   }
   void add_idarray(Id solvid, Id keyname, Id id) {
-    repodata_add_idarray($self->repo->repodata + $self->id, solvid, keyname, id);
+    repodata_add_idarray(repo_id2repodata($self->repo, $self->id), solvid, keyname, id);
   }
   void add_flexarray(Id solvid, Id keyname, Id handle) {
-    repodata_add_flexarray($self->repo->repodata + $self->id, solvid, keyname, handle);
+    repodata_add_flexarray(repo_id2repodata($self->repo, $self->id), solvid, keyname, handle);
   }
   void set_checksum(Id solvid, Id keyname, Chksum *chksum) {
     const unsigned char *buf = solv_chksum_get(chksum, 0);
     if (buf)
-      repodata_set_bin_checksum($self->repo->repodata + $self->id, solvid, keyname, solv_chksum_get_type(chksum), buf);
+      repodata_set_bin_checksum(repo_id2repodata($self->repo, $self->id), solvid, keyname, solv_chksum_get_type(chksum), buf);
   }
   const char *lookup_str(Id solvid, Id keyname) {
-    return repodata_lookup_str($self->repo->repodata + $self->id, solvid, keyname);
+    return repodata_lookup_str(repo_id2repodata($self->repo, $self->id), solvid, keyname);
   }
   Queue lookup_idarray(Id solvid, Id keyname) {
     Queue r;
     queue_init(&r);
-    repodata_lookup_idarray($self->repo->repodata + $self->id, solvid, keyname, &r);
+    repodata_lookup_idarray(repo_id2repodata($self->repo, $self->id), solvid, keyname, &r);
     return r;
   }
   %newobject lookup_checksum;
   Chksum *lookup_checksum(Id solvid, Id keyname) {
     Id type = 0;
-    const unsigned char *b = repodata_lookup_bin_checksum($self->repo->repodata + $self->id, solvid, keyname, &type);
+    const unsigned char *b = repodata_lookup_bin_checksum(repo_id2repodata($self->repo, $self->id), solvid, keyname, &type);
     return solv_chksum_create_from_bin(type, b);
   }
   void internalize() {
-    repodata_internalize($self->repo->repodata + $self->id);
+    repodata_internalize(repo_id2repodata($self->repo, $self->id));
   }
   void create_stubs() {
-    repodata_create_stubs($self->repo->repodata + $self->id);
+    repodata_create_stubs(repo_id2repodata($self->repo, $self->id));
   }
   void write(FILE *fp) {
-    repodata_write($self->repo->repodata + $self->id, fp, repo_write_stdkeyfilter, 0);
+    repodata_write(repo_id2repodata($self->repo, $self->id), fp, repo_write_stdkeyfilter, 0);
   }
   bool add_solv(FILE *fp, int flags = 0) {
-    Repodata *data = $self->repo->repodata + $self->id;
+    Repodata *data = repo_id2repodata($self->repo, $self->id);
     int r, oldstate = data->state;
     data->state = REPODATA_LOADING;
     r = repo_add_solv_flags(data->repo, fp, flags | REPO_USE_LOADING);
@@ -2439,7 +2444,7 @@ rb_eval_string(
     return r;
   }
   void extend_to_repo() {
-    Repodata *data = $self->repo->repodata + $self->id;
+    Repodata *data = repo_id2repodata($self->repo, $self->id);
     repodata_extend_block(data, data->repo->start, data->repo->end - data->repo->start);
   }
   bool __eq__(XRepodata *xr) {
index 9c87f8a..ab86e1d 100644 (file)
@@ -2496,13 +2496,20 @@ rewrite_repos(Pool *pool, Queue *addedfileprovides)
     MAPSET(&providedids, addedfileprovides->elements[i]);
   FOR_REPOS(i, repo)
     {
-      /* make sure this repo has just one main repodata */
-      if (!repo->nrepodata)
-       continue;
-      cinfo = repo->appdata;
-      data = repo->repodata + 1;
-      if (data->store.pagefd == -1)
+      /* make sure all repodatas but the first are extensions */
+      if (repo->nrepodata < 2)
        continue;
+      data = repo_id2repodata(repo, 1);
+      if (data->loadcallback)
+        continue;
+      for (j = 2; j < repo->nrepodata; j++)
+       {
+         Repodata *edata = repo_id2repodata(repo, j);
+         if (!data->loadcallback)
+           break;
+       }
+      if (j < repo->nrepodata)
+       continue;       /* found a non-externsion repodata, can't rewrite  */
       if (repodata_lookup_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &fileprovidesq))
        {
          n = 0;
@@ -2514,6 +2521,7 @@ rewrite_repos(Pool *pool, Queue *addedfileprovides)
        }
       repodata_set_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, addedfileprovides);
       repodata_internalize(data);
+      cinfo = repo->appdata;
       writecachedrepo(repo, data, 0, cinfo ? cinfo->cookie : installedcookie);
     }
   queue_free(&fileprovidesq);
index 679a74a..ab2ba90 100644 (file)
@@ -1,8 +1,8 @@
 SET (libsolvext_SRCS
-    repo_write.c solv_xfopen.c testcase.c)
+    solv_xfopen.c testcase.c)
 
 SET (libsolvext_HEADERS
-    repo_write.h tools_util.h solv_xfopen.h testcase.h)
+    tools_util.h solv_xfopen.h testcase.h)
 
 IF (ENABLE_RPMDB)
     SET (libsolvext_SRCS ${libsolvext_SRCS}
index 865e710..cc28d75 100644 (file)
@@ -22,9 +22,6 @@ SOLV_1.0 {
                repo_add_susetags;
                repo_add_updateinfoxml;
                repo_add_zyppdb_products;
-               repo_write;
-               repo_write_stdkeyfilter;
-               repodata_write;
                rpm_byfp;
                rpm_byrpmdbid;
                rpm_byrpmh;
index b7068b2..25148fd 100644 (file)
@@ -869,6 +869,6 @@ repo_add_helix(Repo *repo, FILE *fp, int flags)
     repodata_internalize(data);
   POOL_DEBUG(SOLV_DEBUG_STATS, "repo_add_helix took %d ms\n", solv_timems(now));
   POOL_DEBUG(SOLV_DEBUG_STATS, "repo size: %d solvables\n", repo->nsolvables);
-  POOL_DEBUG(SOLV_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", data->incoredatalen/1024, repo->idarraysize / (int)(1024/sizeof(Id)));
+  POOL_DEBUG(SOLV_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", repodata_memused(data)/1024, repo->idarraysize / (int)(1024/sizeof(Id)));
   return 0;
 }
index e6ca577..4dcd956 100644 (file)
@@ -1230,12 +1230,8 @@ swap_solvables(Repo *repo, Repodata *data, Id pa, Id pb)
       repo->rpmdbid[pb - repo->start] = tmpid;
     }
   /* only works if nothing is already internalized! */
-  if (data && data->attrs)
-    {
-      Id *tmpattrs = data->attrs[pa - data->start];
-      data->attrs[pa - data->start] = data->attrs[pb - data->start];
-      data->attrs[pb - data->start] = tmpattrs;
-    }
+  if (data)
+    repodata_swap_attrs(data, pa, pb);
 }
 
 
@@ -1737,7 +1733,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, const char *rootdir, int flags)
     pool_debug(pool, SOLV_ERROR, "%%%% 100\n");
   POOL_DEBUG(SOLV_DEBUG_STATS, "repo_add_rpmdb took %d ms\n", solv_timems(now));
   POOL_DEBUG(SOLV_DEBUG_STATS, "repo size: %d solvables\n", repo->nsolvables);
-  POOL_DEBUG(SOLV_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", data->incoredatalen/1024, repo->idarraysize / (int)(1024/sizeof(Id)));
+  POOL_DEBUG(SOLV_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", repodata_memused(data)/1024, repo->idarraysize / (int)(1024/sizeof(Id)));
   return 0;
 }
 
index 668c78d..c2b723f 100644 (file)
@@ -1227,6 +1227,6 @@ repo_add_rpmmd(Repo *repo, FILE *fp, const char *language, int flags)
     repodata_internalize(data);
   POOL_DEBUG(SOLV_DEBUG_STATS, "repo_add_rpmmd took %d ms\n", solv_timems(now));
   POOL_DEBUG(SOLV_DEBUG_STATS, "repo size: %d solvables\n", repo->nsolvables);
-  POOL_DEBUG(SOLV_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", data->incoredatalen/1024, repo->idarraysize / (int)(1024/sizeof(Id)));
+  POOL_DEBUG(SOLV_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", repodata_memused(data)/1024, repo->idarraysize / (int)(1024/sizeof(Id)));
   return 0;
 }
index 98b85ce..06173cc 100644 (file)
@@ -483,22 +483,8 @@ lookup_shared_id(Repodata *data, Id p, Id keyname, Id voidid, int uninternalized
       if (r)
        return r;
     }
-  if (uninternalized && data->attrs)
-    {
-      Id *ap = data->attrs[p - data->start];
-      if (ap)
-       {
-         for (; *ap; ap += 2)
-           {
-             if (data->keys[*ap].name != keyname)
-               continue;
-             if (data->keys[*ap].type == REPOKEY_TYPE_VOID)
-               return voidid;
-             if (data->keys[*ap].type == REPOKEY_TYPE_ID)
-               return ap[1];
-           }
-       }
-    }
+  if (uninternalized)
+    return repodata_lookup_id_uninternalized(data, p, keyname, voidid);
   return 0;
 }
 
index d1ffce1..38be573 100644 (file)
@@ -15,7 +15,7 @@ ADD_DEFINITIONS (-DLIBSOLV_INTERNAL=1)
 
 SET (libsolv_SRCS
     bitmap.c poolarch.c poolvendor.c poolid.c strpool.c dirpool.c
-    solver.c solverdebug.c repo_solv.c evr.c pool.c
+    solver.c solverdebug.c repo_solv.c repo_write.c evr.c pool.c
     queue.c repo.c repodata.c repopage.c util.c policy.c solvable.c
     transaction.c rules.c problems.c
     chksum.c md5.c sha1.c sha2.c solvversion.c)
@@ -23,7 +23,7 @@ SET (libsolv_SRCS
 SET (libsolv_HEADERS
     bitmap.h evr.h hash.h policy.h poolarch.h poolvendor.h pool.h
     poolid.h pooltypes.h queue.h solvable.h solver.h solverdebug.h
-    repo.h repodata.h repopage.h repo_solv.h util.h
+    repo.h repodata.h repopage.h repo_solv.h repo_write.h util.h
     strpool.h dirpool.h knownid.h transaction.h rules.h problems.h
     chksum.h dataiterator.h ${CMAKE_BINARY_DIR}/src/solvversion.h)
 
index e0194ee..568b3ca 100644 (file)
@@ -125,6 +125,7 @@ SOLV_1.0 {
                repo_free;
                repo_free_solvable;
                repo_free_solvable_block;
+               repo_id2repodata;
                repo_internalize;
                repo_last_repodata;
                repo_lookup_bin_checksum;
@@ -146,6 +147,8 @@ SOLV_1.0 {
                repo_set_poolstr;
                repo_set_str;
                repo_sidedata_create;
+               repo_write;
+               repo_write_stdkeyfilter;
                repodata_add_dirnumnum;
                repodata_add_dirstr;
                repodata_add_fixarray;
@@ -153,7 +156,6 @@ SOLV_1.0 {
                repodata_add_idarray;
                repodata_add_poolstr_array;
                repodata_chk2str;
-               repodata_create;
                repodata_create_stubs;
                repodata_delete;
                repodata_delete_uninternalized;
@@ -172,11 +174,13 @@ SOLV_1.0 {
                repodata_localize_id;
                repodata_lookup_bin_checksum;
                repodata_lookup_id;
+               repodata_lookup_id_uninternalized;
                repodata_lookup_idarray;
                repodata_lookup_num;
                repodata_lookup_str;
                repodata_lookup_type;
                repodata_lookup_void;
+               repodata_memused;
                repodata_merge_attrs;
                repodata_merge_some_attrs;
                repodata_new_handle;
@@ -198,6 +202,8 @@ SOLV_1.0 {
                repodata_shrink;
                repodata_str2dir;
                repodata_stringify;
+               repodata_swap_attrs;
+               repodata_write;
                repopagestore_compress_page;
                solv_bin2hex;
                solv_calloc;
index ee9f256..20de966 100644 (file)
@@ -314,6 +314,11 @@ void pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts);
     if ((r = pool->repos[repoid]) != 0)
     
 
+#ifdef ENABLE_COMPS
+#define ISCONDDEP(id) (ISRELDEP(id) && (GETRELDEP(pool, id))->flags == REL_COND)
+#define MODIFYCONDDEP(id, tst) do { Reldep *condrd = GETRELDEP(pool, id); Id condp, condpp; FOR_PROVIDES(condrd->evr, condp, condpp) if (tst) break; id = condp ? condrd->name : 0;} while(0)
+#endif
+
 #define POOL_DEBUG(type, ...) do {if ((pool->debugmask & (type)) != 0) pool_debug(pool, (type), __VA_ARGS__);} while (0)
 #define IF_POOLDEBUG(type) if ((pool->debugmask & (type)) != 0)
 
index 0529681..b61bd0c 100644 (file)
@@ -1311,6 +1311,7 @@ repo_lookup_type(Repo *repo, Id entry, Id keyname)
 Repodata *
 repo_add_repodata(Repo *repo, int flags)
 {
+  Repodata *data;
   int i;
   if ((flags & REPO_USE_LOADING) != 0)
     {
@@ -1332,7 +1333,25 @@ repo_add_repodata(Repo *repo, int flags)
        if (repo->repodata[i].state != REPODATA_STUB)
          return repo->repodata + i;
     }
-  return repodata_create(repo, (flags & REPO_LOCALPOOL) ? 1 : 0);
+  if (!repo->nrepodata)
+    {    
+      repo->nrepodata = 2;      /* start with id 1 */
+      repo->repodata = solv_calloc(repo->nrepodata, sizeof(*data));
+    }    
+  else 
+    {    
+      repo->nrepodata++;
+      repo->repodata = solv_realloc2(repo->repodata, repo->nrepodata, sizeof(*data));
+    }    
+  data = repo->repodata + repo->nrepodata - 1; 
+  repodata_initdata(data, repo, (flags & REPO_LOCALPOOL) ? 1 : 0);
+  return data;
+}
+
+Repodata *
+repo_id2repodata(Repo *repo, Id id)
+{
+  return id ? repo->repodata + id : 0;
 }
 
 Repodata *
index b34c577..022f248 100644 (file)
@@ -39,12 +39,12 @@ typedef struct _Repo {
   Id *idarraydata;             /* array of metadata Ids, solvable dependencies are offsets into this array */
   int idarraysize;
 
-  Repodata *repodata;          /* our stores for non-solvable related data */
   unsigned nrepodata;          /* number of our stores..  */
 
   Id *rpmdbid;                 /* solvable side data: rpm database id */
 
 #ifdef LIBSOLV_INTERNAL
+  Repodata *repodata;          /* our stores for non-solvable related data */
   Offset lastoff;              /* start of last array in idarraydata */
 
   Hashtable lastidhash;                /* hash to speed up repo_addid_dep */
@@ -77,12 +77,6 @@ static inline const char *repo_name(const Repo *repo)
   return repo->name;
 }
 
-static inline Repodata *repo_id2repodata(Repo *repo, Id id)
-{
-  return id ? repo->repodata + id : 0;
-}
-
-
 /* those two functions are here because they need the Repo definition */
 
 static inline Repo *pool_id2repo(Pool *pool, Id repoid)
@@ -121,6 +115,7 @@ static inline int pool_installable(const Pool *pool, Solvable *s)
 #define REPO_EXTEND_SOLVABLES          (1 << 4)
 
 Repodata *repo_add_repodata(Repo *repo, int flags);
+Repodata *repo_id2repodata(Repo *repo, Id id);
 Repodata *repo_last_repodata(Repo *repo);
 
 void repo_search(Repo *repo, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata);
@@ -155,7 +150,12 @@ void repo_disable_paging(Repo *repo);
   for (p = (r)->start, s = (r)->pool->solvables + p; p < (r)->end; p++, s = (r)->pool->solvables + p)  \
     if (s->repo == (r))
 
+#ifdef LIBSOLV_INTERNAL
 #define FOR_REPODATAS(repo, rdid, data)        \
        for (rdid = 1, data = repo->repodata + rdid; rdid < repo->nrepodata; rdid++, data++)
+#else
+#define FOR_REPODATAS(repo, rdid, data)        \
+       for (rdid = 1; rdid < repo->nrepodata && (data = repo_id2repodata(repo, rdid)); rdid++)
+#endif
 
 #endif /* LIBSOLV_REPO_H */
index cbc6c93..2d29001 100644 (file)
@@ -1290,6 +1290,7 @@ printf("=> %s %s %p\n", pool_id2str(pool, keys[key].name), pool_id2str(pool, key
     {
       /* overwrite stub repodata */
       repodata_freedata(parent);
+      data.repodataid = parent->repodataid;
       *parent = data;
     }
   else
@@ -1302,6 +1303,7 @@ printf("=> %s %s %p\n", pool_id2str(pool, keys[key].name), pool_id2str(pool, key
        }
       else
         repo->repodata = solv_realloc2(repo->repodata, repo->nrepodata + 1, sizeof(data));
+      data.repodataid = repo->nrepodata;
       repo->repodata[repo->nrepodata++] = data;
     }
 
similarity index 99%
rename from ext/repo_write.c
rename to src/repo_write.c
index 2fac8ff..1e679b8 100644 (file)
@@ -604,11 +604,13 @@ repo_write_collect_needed(struct cbdata *cbdata, Repo *repo, Repodata *data, Rep
 
   if (key->name == REPOSITORY_SOLVABLES)
     return SEARCH_NEXT_KEY;    /* we do not want this one */
-  if (data != data->repo->repodata + data->repo->nrepodata - 1)
+
+  /* hack: ignore some keys, see BUGS */
+  if (data->repodataid != data->repo->nrepodata - 1)
     if (key->name == REPOSITORY_ADDEDFILEPROVIDES || key->name == REPOSITORY_EXTERNAL || key->name == REPOSITORY_LOCATION || key->name == REPOSITORY_KEYS || key->name == REPOSITORY_TOOLVERSION)
       return SEARCH_NEXT_KEY;
 
-  rm = cbdata->keymap[cbdata->keymapstart[data - data->repo->repodata] + (key - data->keys)];
+  rm = cbdata->keymap[cbdata->keymapstart[data->repodataid] + (key - data->keys)];
   if (!rm)
     return SEARCH_NEXT_KEY;    /* we do not want this one */
 
@@ -722,11 +724,13 @@ repo_write_adddata(struct cbdata *cbdata, Repodata *data, Repokey *key, KeyValue
 
   if (key->name == REPOSITORY_SOLVABLES)
     return SEARCH_NEXT_KEY;
-  if (data != data->repo->repodata + data->repo->nrepodata - 1)
+
+  /* hack: ignore some keys, see BUGS */
+  if (data->repodataid != data->repo->nrepodata - 1)
     if (key->name == REPOSITORY_ADDEDFILEPROVIDES || key->name == REPOSITORY_EXTERNAL || key->name == REPOSITORY_LOCATION || key->name == REPOSITORY_KEYS || key->name == REPOSITORY_TOOLVERSION)
       return SEARCH_NEXT_KEY;
 
-  rm = cbdata->keymap[cbdata->keymapstart[data - data->repo->repodata] + (key - data->keys)];
+  rm = cbdata->keymap[cbdata->keymapstart[data->repodataid] + (key - data->keys)];
   if (!rm)
     return SEARCH_NEXT_KEY;    /* we do not want this one */
   
@@ -1945,6 +1949,6 @@ repodata_write(Repodata *data, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *k
 
   wd.keyfilter = keyfilter;
   wd.kfdata = kfdata;
-  wd.repodataid = data - data->repo->repodata;
+  wd.repodataid = data->repodataid;
   return repo_write(data->repo, fp, repodata_write_keyfilter, &wd, 0);
 }
similarity index 100%
rename from ext/repo_write.h
rename to src/repo_write.h
index 5e5cfed..106b983 100644 (file)
@@ -42,6 +42,7 @@ void
 repodata_initdata(Repodata *data, Repo *repo, int localpool)
 {
   memset(data, 0, sizeof (*data));
+  data->repodataid = data - repo->repodata;
   data->repo = repo;
   data->localpool = localpool;
   if (localpool)
@@ -92,34 +93,21 @@ repodata_freedata(Repodata *data)
   solv_free(data->attriddata);
 }
 
-Repodata *
-repodata_create(Repo *repo, int localpool)
-{
-  Repodata *data;
-
-  if (!repo->nrepodata)
-    {
-      repo->nrepodata = 2;     /* start with id 1 */
-      repo->repodata = solv_calloc(repo->nrepodata, sizeof(*data));
-    }
-  else
-    {
-      repo->nrepodata++;
-      repo->repodata = solv_realloc2(repo->repodata, repo->nrepodata, sizeof(*data));
-    }
-  data = repo->repodata + repo->nrepodata - 1;
-  repodata_initdata(data, repo, localpool);
-  return data;
-}
-
 void
 repodata_free(Repodata *data)
 {
   Repo *repo = data->repo;
   int i = data - repo->repodata;
+  if (i == 0)
+    return;
   repodata_freedata(data);
   if (i < repo->nrepodata - 1)
-    memmove(repo->repodata + i, repo->repodata + i + 1, (repo->nrepodata - 1 - i) * sizeof(Repodata));
+    {
+      /* whoa! this changes the repodataids! */
+      memmove(repo->repodata + i, repo->repodata + i + 1, (repo->nrepodata - 1 - i) * sizeof(Repodata));
+      for (; i < repo->nrepodata - 1; i++)
+       repo->repodata[i].repodataid = i;
+    }
   repo->nrepodata--;
   if (repo->nrepodata == 1)
     {
@@ -723,6 +711,28 @@ repodata_localize_id(Repodata *data, Id id, int create)
   return stringpool_str2id(&data->spool, pool_id2str(data->repo->pool, id), create);
 }
 
+Id
+repodata_lookup_id_uninternalized(Repodata *data, Id solvid, Id keyname, Id voidid)
+{
+  Id *ap;
+  if (!data->attrs)
+    return 0;
+  ap = data->attrs[solvid - data->start];
+  if (!ap)
+    return 0;
+  for (; *ap; ap += 2)
+    {
+      if (data->keys[*ap].name != keyname)
+       continue;
+      if (data->keys[*ap].type == REPOKEY_TYPE_VOID)
+       return voidid;
+      if (data->keys[*ap].type == REPOKEY_TYPE_ID)
+       return ap[1];
+      return 0;
+    }
+  return 0;
+}
+
 
 /************************************************************************
  * data search
@@ -2356,7 +2366,7 @@ void
 repodata_merge_attrs(Repodata *data, Id dest, Id src)
 {
   Id *keyp;
-  if (dest == src || !(keyp = data->attrs[src - data->start]))
+  if (dest == src || data->attrs || !(keyp = data->attrs[src - data->start]))
     return;
   for (; *keyp; keyp += 2)
     repodata_insert_keyid(data, dest, keyp[0], keyp[1], 0);
@@ -2367,13 +2377,24 @@ void
 repodata_merge_some_attrs(Repodata *data, Id dest, Id src, Map *keyidmap, int overwrite)
 {
   Id *keyp;
-  if (dest == src || !(keyp = data->attrs[src - data->start]))
+  if (dest == src || !data->attrs || !(keyp = data->attrs[src - data->start]))
     return;
   for (; *keyp; keyp += 2)
     if (!keyidmap || MAPTST(keyidmap, keyp[0]))
       repodata_insert_keyid(data, dest, keyp[0], keyp[1], overwrite);
 }
 
+/* swap (uninternalized) attrs from src and dest */
+void
+repodata_swap_attrs(Repodata *data, Id dest, Id src)
+{
+  Id *tmpattrs;
+  if (!data->attrs || dest == src)
+    return;
+  tmpattrs = data->attrs[dest - data->start];
+  data->attrs[dest - data->start] = data->attrs[src - data->start];
+  data->attrs[src - data->start] = tmpattrs;
+}
 
 
 /**********************************************************************/
@@ -2915,6 +2936,12 @@ repodata_create_stubs(Repodata *data)
   solv_free(stubdataids);
 }
 
+unsigned int
+repodata_memused(Repodata *data)
+{
+  return data->incoredatalen + data->vincorelen;
+}
+
 /*
 vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4:
 */
index ff23a6b..938bd83 100644 (file)
@@ -41,6 +41,7 @@ typedef struct _Repokey {
 
 
 typedef struct _Repodata {
+  Id repodataid;               /* our id */
   struct _Repo *repo;          /* back pointer to repo */
 
 #define REPODATA_AVAILABLE     0
@@ -74,6 +75,8 @@ typedef struct _Repodata {
 
   Dirpool dirpool;             /* local dir pool */
 
+#ifdef LIBSOLV_INTERNAL
+
   unsigned char *incoredata;   /* in-core data */
   unsigned int incoredatalen;  /* in-core data used */
   unsigned int incoredatafree; /* free data len */
@@ -105,6 +108,8 @@ typedef struct _Repodata {
   Id lastkey;
   Id lastdatalen;
 
+#endif
+
 } Repodata;
 
 #define SOLVID_META            -1
@@ -118,7 +123,6 @@ typedef struct _Repodata {
 void repodata_initdata(Repodata *data, struct _Repo *repo, int localpool);
 void repodata_freedata(Repodata *data);
 
-Repodata *repodata_create(struct _Repo *repo, int localpool);
 void repodata_free(Repodata *data);
 void repodata_empty(Repodata *data, int localpool);
 
@@ -251,11 +255,12 @@ void repodata_delete(Repodata *data, Id solvid, Id keyname);
 void repodata_delete_uninternalized(Repodata *data, Id solvid, Id keyname);
 
 /* 
- merge attributes from one solvable to another
+ merge/swap attributes from one solvable to another
  works only if the data is not yet internalized
 */
 void repodata_merge_attrs(Repodata *data, Id dest, Id src);
 void repodata_merge_some_attrs(Repodata *data, Id dest, Id src, Map *keyidmap, int overwrite);
+void repodata_swap_attrs(Repodata *data, Id dest, Id src);
 
 void repodata_create_stubs(Repodata *data);
 void repodata_join(Repodata *data, Id joinkey);
@@ -272,5 +277,9 @@ Id repodata_str2dir(Repodata *data, const char *dir, int create);
 const char *repodata_dir2str(Repodata *data, Id did, const char *suf);
 const char *repodata_chk2str(Repodata *data, Id type, const unsigned char *buf);
 void repodata_set_location(Repodata *data, Id solvid, int medianr, const char *dir, const char *file);
+Id repodata_lookup_id_uninternalized(Repodata *data, Id solvid, Id keyname, Id voidid);
+
+/* stats */
+unsigned int repodata_memused(Repodata *data);
 
 #endif /* LIBSOLV_REPODATA_H */