Imported Upstream version 0.7.2
[platform/upstream/libsolv.git] / ext / repo_rpmdb.c
index daf22e9..9acb400 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,23 +1409,19 @@ 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, cbdata->dircache);
+      kv->id = repodata_translate_dir(data, fromdata, kv->id, 1, fromdata->repodataid == 1 ? cbdata->dircache : 0);
       break;
+    case REPOKEY_TYPE_FIXARRAY:
+      cbdata->handle = repodata_new_handle(data);
+      repodata_add_fixarray(data, handle, key->name, cbdata->handle);
+      repodata_search_arrayelement(fromdata, 0, 0, 0, kv, &solvable_copy_cb, cbdata);
+      cbdata->handle = handle;
+      return 0;
     case REPOKEY_TYPE_FLEXARRAY:
-      if (kv->eof == 2)
-       {
-         assert(cbdata->subhandle);
-         cbdata->handle = cbdata->subhandle;
-         cbdata->subhandle = 0;
-         break;
-       }
-      if (!kv->entry)
-        {
-         assert(!cbdata->subhandle);
-         cbdata->subhandle = cbdata->handle;
-       }
       cbdata->handle = repodata_new_handle(data);
-      repodata_add_flexarray(data, cbdata->subhandle, key->name, cbdata->handle);
+      repodata_add_flexarray(data, handle, key->name, cbdata->handle);
+      repodata_search_arrayelement(fromdata, 0, 0, 0, kv, &solvable_copy_cb, cbdata);
+      cbdata->handle = handle;
       return 0;
     default:
       break;
@@ -1473,13 +1431,14 @@ solvable_copy_cb(void *vcbdata, Solvable *r, Repodata *fromdata, Repokey *key, K
 }
 
 static void
-solvable_copy(Solvable *s, Solvable *r, Repodata *data, Id *dircache)
+solvable_copy(Solvable *s, Solvable *r, Repodata *data, Id *dircache, Id **oldkeyskip)
 {
   int p, i;
   Repo *repo = s->repo;
   Pool *pool = repo->pool;
   Repo *fromrepo = r->repo;
   struct solvable_copy_cbdata cbdata;
+  Id *keyskip;
 
   /* copy solvable data */
   s->name = r->name;
@@ -1507,19 +1466,15 @@ solvable_copy(Solvable *s, Solvable *r, Repodata *data, Id *dircache)
     {
       Repodata *fromdata = repo_id2repodata(fromrepo, 1);
       if (p >= fromdata->start && p < fromdata->end)
-        repodata_search(fromdata, p, 0, SEARCH_SUB | SEARCH_ARRAYSENTINEL, solvable_copy_cb, &cbdata);
+        repodata_search(fromdata, p, 0, 0, solvable_copy_cb, &cbdata);
       return;
     }
-#if 0
-  repo_search(fromrepo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE | SEARCH_SUB | SEARCH_ARRAYSENTINEL, solvable_copy_cb, &cbdata);
-#else
+  keyskip = repo_create_keyskip(repo, p, oldkeyskip);
   FOR_REPODATAS(fromrepo, i, data)
     {
       if (p >= data->start && p < data->end)
-        repodata_search(data, p, 0, SEARCH_SUB | SEARCH_ARRAYSENTINEL, solvable_copy_cb, &cbdata);
-      cbdata.dircache = 0;     /* only for first repodata */
+        repodata_search_keyskip(data, p, 0, 0, keyskip, solvable_copy_cb, &cbdata);
     }
-#endif
 }
 
 /* used to sort entries by package name that got returned in some database order */
@@ -1706,9 +1661,8 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
       if (s)
        {
          /* oops, could not reuse. free it instead */
-          repo_free_solvable(repo, s - pool->solvables, 1);
+          s = solvable_free(s, 1);
          solvend--;
-         s = 0;
        }
       /* now sort all solvables in the new solvstart..solvend block */
       if (solvend - solvstart > 1)
@@ -1731,7 +1685,8 @@ 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;
       char *namedata = 0;
@@ -1739,8 +1694,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)
@@ -1795,10 +1748,11 @@ 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;
-         repo->rpmdbid[(s - pool->solvables) - repo->start] = rp->rpmdbid;
+         repo->rpmdbid[(s - pool->solvables) - repo->start] = dbid;
          if (refhash)
            {
              h = dbid & refmask;
@@ -1813,7 +1767,7 @@ repo_add_rpmdb(Repo *repo, Repo *ref, int flags)
                  Solvable *r = ref->pool->solvables + ref->start + (id - 1);
                  if (r->repo == ref)
                    {
-                     solvable_copy(s, r, data, dircache);
+                     solvable_copy(s, r, data, dircache, &oldkeyskip);
                      continue;
                    }
                }
@@ -1827,6 +1781,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);
@@ -1838,7 +1793,9 @@ 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);
       solv_free(namedata);
       solv_free(refhash);
@@ -1939,8 +1896,6 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
   if (fread(lead, 96 + 16, 1, fp) != 1 || getu32(lead) != 0xedabeedb)
     {
       pool_error(pool, -1, "%s: not a rpm", rpm);
-      solv_chksum_free(leadsigchksumh, 0);
-      solv_chksum_free(chksumh, 0);
       fclose(fp);
       return 0;
     }
@@ -1953,16 +1908,12 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
   if (lead[78] != 0 || lead[79] != 5)
     {
       pool_error(pool, -1, "%s: not a rpm v5 header", rpm);
-      solv_chksum_free(leadsigchksumh, 0);
-      solv_chksum_free(chksumh, 0);
       fclose(fp);
       return 0;
     }
   if (getu32(lead + 96) != 0x8eade801)
     {
       pool_error(pool, -1, "%s: bad signature header", rpm);
-      solv_chksum_free(leadsigchksumh, 0);
-      solv_chksum_free(chksumh, 0);
       fclose(fp);
       return 0;
     }
@@ -1971,8 +1922,6 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
   if (sigcnt >= MAX_SIG_CNT || sigdsize >= MAX_SIG_DSIZE)
     {
       pool_error(pool, -1, "%s: bad signature header", rpm);
-      solv_chksum_free(leadsigchksumh, 0);
-      solv_chksum_free(chksumh, 0);
       fclose(fp);
       return 0;
     }
@@ -1983,8 +1932,6 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
     {
       if (!headfromfp(&state, rpm, fp, lead + 96, sigcnt, sigdsize, sigpad, chksumh, leadsigchksumh))
        {
-      solv_chksum_free(leadsigchksumh, 0);
-      solv_chksum_free(chksumh, 0);
          fclose(fp);
          return 0;
        }
@@ -2024,8 +1971,6 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
          if (fread(lead, l, 1, fp) != 1)
            {
              pool_error(pool, -1, "%s: unexpected EOF", rpm);
-             solv_chksum_free(leadsigchksumh, 0);
-             solv_chksum_free(chksumh, 0);
              fclose(fp);
              return 0;
            }
@@ -2046,7 +1991,6 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
   if (fread(lead, 16, 1, fp) != 1)
     {
       pool_error(pool, -1, "%s: unexpected EOF", rpm);
-      solv_chksum_free(chksumh, 0);
       fclose(fp);
       return 0;
     }
@@ -2055,7 +1999,6 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
   if (getu32(lead) != 0x8eade801)
     {
       pool_error(pool, -1, "%s: bad header", rpm);
-      solv_chksum_free(chksumh, 0);
       fclose(fp);
       return 0;
     }
@@ -2064,7 +2007,6 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
   if (sigcnt >= MAX_HDR_CNT || sigdsize >= MAX_HDR_DSIZE)
     {
       pool_error(pool, -1, "%s: bad header", rpm);
-      solv_chksum_free(chksumh, 0);
       fclose(fp);
       return 0;
     }
@@ -2072,7 +2014,6 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
 
   if (!headfromfp(&state, rpm, fp, lead, sigcnt, sigdsize, 0, chksumh, 0))
     {
-      solv_chksum_free(chksumh, 0);
       fclose(fp);
       return 0;
     }
@@ -2102,7 +2043,7 @@ repo_add_rpm(Repo *repo, const char *rpm, int flags)
   s = pool_id2solvable(pool, repo_add_solvable(repo));
   if (!rpmhead2solv(pool, repo, data, s, state.rpmhead, flags & ~(RPM_ADD_WITH_HDRID | RPM_ADD_WITH_PKGID)))
     {
-      repo_free_solvable(repo, s - pool->solvables, 1);
+      s = solvable_free(s, 1);
       solv_chksum_free(chksumh, 0);
       headfree(state.rpmhead);
       return 0;
@@ -2154,7 +2095,7 @@ repo_add_rpm_handle(Repo *repo, void *rpmhandle, int flags)
   s = pool_id2solvable(pool, repo_add_solvable(repo));
   if (!rpmhead2solv(pool, repo, data, s, rpmhead, flags))
     {
-      repo_free_solvable(repo, s - pool->solvables, 1);
+      s = solvable_free(s, 1);
       return 0;
     }
   if (!(flags & REPO_NO_INTERNALIZE))