]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Add repodata_translate_dir method
authorMichael Schroeder <mls@suse.de>
Tue, 18 Sep 2018 12:49:57 +0000 (14:49 +0200)
committerMichael Schroeder <mls@suse.de>
Tue, 18 Sep 2018 12:49:57 +0000 (14:49 +0200)
This translates a dir id from one repodata to another. Change
repo_rpmdb to use it when copying solvables.

ext/repo_rpmdb.c
src/libsolv.ver
src/repodata.c
src/repodata.h

index 3a5c114b3640345cd10a88443e64d8e9bedd725d..e01993ce1c382fc12e3cd0ced9dd042762ddec89 100644 (file)
@@ -1385,44 +1385,6 @@ copydeps(Pool *pool, Repo *repo, Offset fromoff, Repo *fromrepo)
   return ido;
 }
 
-#define COPYDIR_DIRCACHE_SIZE 512
-
-static Id copydir_complex(Repodata *data, Repodata *fromdata, Id did, Id *cache);
-
-static inline Id
-copydir(Repodata *data, Repodata *fromdata, Id did, Id *cache)
-{
-  if (cache && did && cache[did & 255] == did)
-    return cache[(did & 255) + 256];
-  return copydir_complex(data, fromdata, did, cache);
-}
-
-static Id
-copydir_complex(Repodata *data, Repodata *fromdata, Id did, Id *cache)
-{
-  Id parent, compid;
-  if (!did)
-    {
-      /* make sure that the dirpool has an entry */
-      if (!data->dirpool.ndirs)
-        dirpool_add_dir(&data->dirpool, 0, 0, 1);
-      return 0;
-    }
-  parent = dirpool_parent(&fromdata->dirpool, did);
-  compid = dirpool_compid(&fromdata->dirpool, did);
-  if (parent)
-    parent = copydir(data, fromdata, parent, cache);
-  if (data->localpool || fromdata->localpool)
-    compid = repodata_translate_id(data, fromdata, compid, 1);
-  compid = dirpool_add_dir(&data->dirpool, parent, compid, 1);
-  if (cache)
-    {
-      cache[did & 255] = did;
-      cache[(did & 255) + 256] = compid;
-    }
-  return compid;
-}
-
 struct solvable_copy_cbdata {
   Repodata *data;
   Id handle;
@@ -1447,7 +1409,7 @@ solvable_copy_cb(void *vcbdata, Solvable *r, Repodata *fromdata, Repokey *key, K
       break;
     case REPOKEY_TYPE_DIRNUMNUMARRAY:
     case REPOKEY_TYPE_DIRSTRARRAY:
-      kv->id = copydir(data, fromdata, kv->id, data->repodataid == 1 ? cbdata->dircache : 0);
+      kv->id = repodata_translate_dir(data, fromdata, kv->id, 1, fromdata->repodataid == 1 ? cbdata->dircache : 0);
       break;
     case REPOKEY_TYPE_FLEXARRAY:
       if (kv->eof == 2)
@@ -1732,7 +1694,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
     }
   else
     {
-      Id dircache[COPYDIR_DIRCACHE_SIZE];              /* see copydir */
+      Id *dircache;
       Id *oldkeyskip = 0;
       struct rpmdbentry *entries = 0, *rp;
       int nentries = 0;
@@ -1741,8 +1703,6 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
       Id id, *refhash;
       int res;
 
-      memset(dircache, 0, sizeof(dircache));
-
       /* get ids of installed rpms */
       entries = getinstalledrpmdbids(&state, "Name", 0, &nentries, &namedata, flags & RPMDB_KEEP_GPG_PUBKEY);
       if (!entries)
@@ -1797,6 +1757,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
       if (!repo->rpmdbid)
         repo->rpmdbid = repo_sidedata_create(repo, sizeof(Id));
 
+      dircache = repodata_create_dirtranscache(data);
       for (i = 0, rp = entries; i < nentries; i++, rp++, s++)
        {
          Id dbid = rp->rpmdbid;
@@ -1829,6 +1790,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
              solv_free(entries);
              solv_free(namedata);
              solv_free(refhash);
+             dircache = repodata_free_dirtranscache(dircache);
              return -1;
            }
          rpmhead2solv(pool, repo, data, s, state.rpmhead, flags | RPM_ADD_TRIGGERS);
@@ -1840,6 +1802,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
                pool_debug(pool, SOLV_ERROR, "%%%% %d\n", done * 100 / count);
            }
        }
+      dircache = repodata_free_dirtranscache(dircache);
 
       solv_free(oldkeyskip);
       solv_free(entries);
index 684f20fdbfad5795d08466a4552167d561adda5f..e6bff90c19fceb77616ab429bc7c2fa664aa980a 100644 (file)
@@ -240,6 +240,7 @@ SOLV_1.0 {
                repodata_str2dir;
                repodata_stringify;
                repodata_swap_attrs;
+               repodata_translate_dir_slow;
                repodata_translate_id;
                repodata_unset;
                repodata_unset_uninternalized;
index 5e5cbe20af72cbce6f3a588eb16e3d623780e7ae..b4aa714782ed62209811c64f159da3656f8f63d3 100644 (file)
@@ -889,18 +889,52 @@ repodata_localize_id(Repodata *data, Id id, int create)
 Id
 repodata_translate_id(Repodata *data, Repodata *fromdata, Id id, int create)
 {
+  const char *s;
   if (!id || !data || !fromdata)
     return id;
-  if (!data->localpool || !fromdata->localpool)
+  if (data == fromdata || (!data->localpool && !fromdata->localpool))
+    return id;
+  if (fromdata->localpool)
+    s = stringpool_id2str(&fromdata->spool, id);
+  else
+    s = pool_id2str(data->repo->pool, id);
+  if (data->localpool)
+    return stringpool_str2id(&data->spool, s, create);
+  else
+    return pool_str2id(data->repo->pool, s, create);
+}
+
+Id
+repodata_translate_dir_slow(Repodata *data, Repodata *fromdata, Id dir, int create, Id *cache)
+{
+  Id parent, compid;
+  if (!dir)
     {
-      if (fromdata->localpool)
-       id = repodata_globalize_id(fromdata, id, create);
-      if (data->localpool)
-       id = repodata_localize_id(data, id, create);
-      return id;
+      /* make sure that the dirpool has an entry */
+      if (create && !data->dirpool.ndirs)
+        dirpool_add_dir(&data->dirpool, 0, 0, create);
+      return 0;
+    }
+  parent = dirpool_parent(&fromdata->dirpool, dir);
+  if (parent)
+    {
+      if (!(parent = repodata_translate_dir(data, fromdata, parent, create, cache)))
+       return 0;
+    }
+  compid = dirpool_compid(&fromdata->dirpool, dir);
+  if (compid > 1 && (data->localpool || fromdata->localpool))
+    {
+      if (!(compid = repodata_translate_id(data, fromdata, compid, create)))
+       return 0;
+    }
+  if (!(compid = dirpool_add_dir(&data->dirpool, parent, compid, create)))
+    return 0;
+  if (cache)
+    {
+      cache[(dir & 255) * 2] = dir;
+      cache[(dir & 255) * 2 + 1] = compid;
     }
-  /* localpool is set in both data and fromdata */
-  return stringpool_str2id(&data->spool, stringpool_id2str(&fromdata->spool, id), create);
+  return compid;
 }
 
 /* uninternalized lookups */
index f13d79972c47d33e84b6c84a3076f960ce206478..a6ecd9677e489803ea2c6e9e20b07b03dae4d47f 100644 (file)
@@ -314,6 +314,7 @@ void repodata_disable_paging(Repodata *data);
 Id repodata_globalize_id(Repodata *data, Id id, int create);
 Id repodata_localize_id(Repodata *data, Id id, int create);
 Id repodata_translate_id(Repodata *data, Repodata *fromdata, Id id, int create);
+Id repodata_translate_dir_slow(Repodata *data, Repodata *fromdata, Id dir, int create, Id *cache);
 
 Id repodata_str2dir(Repodata *data, const char *dir, int create);
 const char *repodata_dir2str(Repodata *data, Id did, const char *suf);
@@ -330,6 +331,27 @@ const unsigned char *repodata_lookup_bin_checksum_uninternalized(Repodata *data,
 /* stats */
 unsigned int repodata_memused(Repodata *data);
 
+static inline Id
+repodata_translate_dir(Repodata *data, Repodata *fromdata, Id dir, int create, Id *cache)
+{
+  if (cache && dir && cache[(dir & 255) * 2] == dir)
+    return cache[(dir & 255) * 2 + 1];
+  return repodata_translate_dir_slow(data, fromdata, dir, create, cache);
+}
+
+static inline Id *
+repodata_create_dirtranscache(Repodata *data)
+{
+  return solv_calloc(256, sizeof(Id) * 2);
+}
+
+static inline Id *
+repodata_free_dirtranscache(Id *cache)
+{
+  return solv_free(cache);
+}
+
+
 #ifdef __cplusplus
 }
 #endif