- fix di->repoid to be consistent with repo->repoid
[platform/upstream/libsolv.git] / src / repodata.c
index bde6579..55517c5 100644 (file)
 #include "repopack.h"
 #include "repopage.h"
 
-extern unsigned int compress_buf (const unsigned char *in, unsigned int in_len,
-                                 unsigned char *out, unsigned int out_len);
-extern unsigned int unchecked_decompress_buf (const unsigned char *in,
-                                             unsigned int in_len,
-                                             unsigned char *out,
-                                             unsigned int out_len);
-
 #define REPODATA_BLOCK 255
 
+static unsigned char *data_skip_key(Repodata *data, unsigned char *dp, Repokey *key);
 
 void
 repodata_initdata(Repodata *data, Repo *repo, int localpool)
@@ -52,6 +46,7 @@ repodata_initdata(Repodata *data, Repo *repo, int localpool)
   data->localpool = localpool;
   if (localpool)
     stringpool_init_empty(&data->spool);
+  /* dirpool_init(&data->dirpool);     just zeros out again */
   data->keys = sat_calloc(1, sizeof(Repokey));
   data->nkeys = 1;
   data->schemata = sat_calloc(1, sizeof(Id));
@@ -182,15 +177,17 @@ repodata_schema2id(Repodata *data, Id *schema, int create)
   Id *sp, cid;
   Id *schematahash;
 
+  if (!*schema)
+    return 0;  /* XXX: allow empty schema? */
   if ((schematahash = data->schematahash) == 0)
     {
       data->schematahash = schematahash = sat_calloc(256, sizeof(Id));
-      for (i = 0; i < data->nschemata; i++)
+      for (i = 1; i < data->nschemata; i++)
        {
          for (sp = data->schemadata + data->schemata[i], h = 0; *sp; len++)
            h = h * 7 + *sp++;
          h &= 255;
-         schematahash[h] = i + 1;
+         schematahash[h] = i;
        }
       data->schemadata = sat_extend_resize(data->schemadata, data->schemadatalen, sizeof(Id), SCHEMATADATA_BLOCK);
       data->schemata = sat_extend_resize(data->schemata, data->nschemata, sizeof(Id), SCHEMATA_BLOCK);
@@ -204,11 +201,10 @@ repodata_schema2id(Repodata *data, Id *schema, int create)
   cid = schematahash[h];
   if (cid)
     {
-      cid--;
       if (!memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id)))
         return cid;
-      /* cache conflict */
-      for (cid = 0; cid < data->nschemata; cid++)
+      /* cache conflict, do a slow search */
+      for (cid = 1; cid < data->nschemata; cid++)
         if (!memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id)))
           return cid;
     }
@@ -221,7 +217,7 @@ repodata_schema2id(Repodata *data, Id *schema, int create)
   memcpy(data->schemadata + data->schemadatalen, schema, len * sizeof(Id));
   data->schemata[data->nschemata] = data->schemadatalen;
   data->schemadatalen += len;
-  schematahash[h] = data->nschemata + 1;
+  schematahash[h] = data->nschemata;
 #if 0
 fprintf(stderr, "schema2id: new schema\n");
 #endif
@@ -271,7 +267,7 @@ repodata_str2dir(Repodata *data, const char *dir, int create)
       if (data->localpool)
         id = stringpool_strn2id(&data->spool, dir, dire - dir, create);
       else
-       id = strn2id(data->repo->pool, dir, dire - dir, create);
+       id = pool_strn2id(data->repo->pool, dir, dire - dir, create);
       if (!id)
        return 0;
       parent = dirpool_add_dir(&data->dirpool, parent, id, create);
@@ -346,7 +342,7 @@ data_skip_schema(Repodata *data, unsigned char *dp, Id schema)
   return dp;
 }
 
-unsigned char *
+static unsigned char *
 data_skip_key(Repodata *data, unsigned char *dp, Repokey *key)
 {
   int nentries, schema;
@@ -429,10 +425,10 @@ get_vertical_data(Repodata *data, Repokey *key, Id off, Id len)
     return 0;
   /* we now have the offset, go into vertical */
   off += data->verticaloffset[key - data->keys];
-  /* fprintf(stderr, "key %d page %d\n", key->name, off / BLOB_PAGESIZE); */
-  dp = repopagestore_load_page_range(&data->store, off / BLOB_PAGESIZE, (off + len - 1) / BLOB_PAGESIZE);
+  /* fprintf(stderr, "key %d page %d\n", key->name, off / REPOPAGE_BLOBSIZE); */
+  dp = repopagestore_load_page_range(&data->store, off / REPOPAGE_BLOBSIZE, (off + len - 1) / REPOPAGE_BLOBSIZE);
   if (dp)
-    dp += off % BLOB_PAGESIZE;
+    dp += off % REPOPAGE_BLOBSIZE;
   return dp;
 }
 
@@ -609,14 +605,14 @@ repodata_lookup_str(Repodata *data, Id solvid, Id keyname)
   if (key->type == REPOKEY_TYPE_STR)
     return (const char *)dp;
   if (key->type == REPOKEY_TYPE_CONSTANTID)
-    return id2str(data->repo->pool, key->size);
-  if (key->type == REPOKEY_TYPE_ID)
+    id = key->size;
+  else if (key->type == REPOKEY_TYPE_ID)
     dp = data_read_id(dp, &id);
   else
     return 0;
   if (data->localpool)
-    return data->spool.stringspace + data->spool.strings[id];
-  return id2str(data->repo->pool, id);
+    return stringpool_id2str(&data->spool, id);
+  return pool_id2str(data->repo->pool, id);
 }
 
 int
@@ -634,6 +630,7 @@ repodata_lookup_num(Repodata *data, Id solvid, Id keyname, unsigned int *value)
       || key->type == REPOKEY_TYPE_U32
       || key->type == REPOKEY_TYPE_CONSTANT)
     {
+      kv.num = 0;
       dp = data_fetch(dp, &kv, key);
       *value = kv.num;
       return 1;
@@ -702,7 +699,15 @@ repodata_globalize_id(Repodata *data, Id id, int create)
 {
   if (!id || !data || !data->localpool)
     return id;
-  return str2id(data->repo->pool, stringpool_id2str(&data->spool, id), create);
+  return pool_str2id(data->repo->pool, stringpool_id2str(&data->spool, id), create);
+}
+
+Id
+repodata_localize_id(Repodata *data, Id id, int create)
+{
+  if (!id || !data || !data->localpool)
+    return id;
+  return stringpool_str2id(&data->spool, pool_id2str(data->repo->pool, id), create);
 }
 
 
@@ -722,7 +727,7 @@ repodata_stringify(Pool *pool, Repodata *data, Repokey *key, KeyValue *kv, int f
       if (data && data->localpool)
        kv->str = stringpool_id2str(&data->spool, kv->id);
       else
-       kv->str = id2str(pool, kv->id);
+       kv->str = pool_id2str(pool, kv->id);
       if ((flags & SEARCH_SKIP_KIND) != 0 && key->storage == KEY_STORAGE_SOLVABLE)
        {
          const char *s;
@@ -1171,7 +1176,7 @@ void
 dataiterator_set_search(Dataiterator *di, Repo *repo, Id p)
 {
   di->repo = repo;
-  di->repoid = -1;
+  di->repoid = 0;
   di->flags &= ~SEARCH_THISSOLVID;
   di->nparents = 0;
   di->rootlevel = 0;
@@ -1183,7 +1188,7 @@ dataiterator_set_search(Dataiterator *di, Repo *repo, Id p)
     }
   if (!repo)
     {
-      di->repoid = 0;
+      di->repoid = 1;
       di->repo = di->pool->repos[0];
     }
   di->state = di_enterrepo;
@@ -1378,13 +1383,13 @@ dataiterator_step(Dataiterator *di)
          /* FALLTHROUGH */
 
        case di_nextrepo: di_nextrepo:
-         if (di->repoid >= 0)
+         if (di->repoid > 0)
            {
              di->repoid++;
              di->repodataid = 0;
-             if (di->repoid < di->pool->nrepos)
+             if (di->repoid - 1 < di->pool->nrepos)
                {
-                 di->repo = di->pool->repos[di->repoid];
+                 di->repo = di->pool->repos[di->repoid - 1];
                  goto di_enterrepo;
                }
            }
@@ -1671,7 +1676,7 @@ dataiterator_jump_to_solvid(Dataiterator *di, Id solvid)
          di->state = di_bye;
          return;
        }
-      di->repoid = -1;
+      di->repoid = 0;
       di->data = di->repo->repodata + di->pool->pos.repodataid;
       di->repodataid = -1;
       di->solvid = solvid;
@@ -1682,17 +1687,17 @@ dataiterator_jump_to_solvid(Dataiterator *di, Id solvid)
   if (solvid > 0)
     {
       di->repo = di->pool->solvables[solvid].repo;
-      di->repoid = -1;
+      di->repoid = 0;
     }
-  else if (di->repoid >= 0)
+  else if (di->repoid > 0)
     {
       if (!di->pool->nrepos)
        {
          di->state = di_bye;
          return;
        }
+      di->repoid = 1;
       di->repo = di->pool->repos[0];
-      di->repoid = 0;
     }
   di->repodataid = 0;
   di->solvid = solvid;
@@ -1708,7 +1713,7 @@ dataiterator_jump_to_repo(Dataiterator *di, Repo *repo)
   di->kv.parent = 0;
   di->rootlevel = 0;
   di->repo = repo;
-  di->repoid = -1;
+  di->repoid = 0;      /* 0 means stay at repo */
   di->repodataid = 0;
   di->solvid = 0;
   di->flags &= ~SEARCH_THISSOLVID;
@@ -1828,7 +1833,7 @@ repodata_new_handle(Repodata *data)
   if (!data->nxattrs)
     {
       data->xattrs = sat_calloc_block(1, sizeof(Id *), REPODATA_BLOCK);
-      data->nxattrs = 2;
+      data->nxattrs = 2;       /* -1: SOLVID_META */
     }
   data->xattrs = sat_extend(data->xattrs, data->nxattrs, 1, sizeof(Id *), REPODATA_BLOCK);
   data->xattrs[data->nxattrs] = 0;
@@ -1838,16 +1843,15 @@ repodata_new_handle(Repodata *data)
 static inline Id **
 repodata_get_attrp(Repodata *data, Id handle)
 {
-  if (handle == SOLVID_META)
+  if (handle < 0)
     {
-      if (!data->xattrs)
+      if (handle == SOLVID_META && !data->xattrs)
        {
          data->xattrs = sat_calloc_block(1, sizeof(Id *), REPODATA_BLOCK);
           data->nxattrs = 2;
        }
+      return data->xattrs - handle;
     }
-  if (handle < 0)
-    return data->xattrs - handle;
   if (handle < data->start || handle >= data->end)
     repodata_extend(data, handle);
   if (!data->attrs)
@@ -1931,7 +1935,7 @@ repodata_set_poolstr(Repodata *data, Id solvid, Id keyname, const char *str)
   if (data->localpool)
     id = stringpool_str2id(&data->spool, str, 1);
   else
-    id = str2id(data->repo->pool, str, 1);
+    id = pool_str2id(data->repo->pool, str, 1);
   key.name = keyname;
   key.type = REPOKEY_TYPE_ID;
   key.size = 0;
@@ -2130,7 +2134,7 @@ repodata_chk2str(Repodata *data, Id type, const unsigned char *buf)
 static inline const char *
 evrid2vrstr(Pool *pool, Id evrid)
 {
-  const char *p, *evr = id2str(pool, evrid);
+  const char *p, *evr = pool_id2str(pool, evrid);
   if (!evr)
     return evr;
   for (p = evr; *p >= '0' && *p <= '9'; p++)
@@ -2171,7 +2175,7 @@ repodata_set_location(Repodata *data, Id solvid, int medianr, const char *dir, c
   s = pool->solvables + solvid;
   if (dir && l)
     {
-      str = id2str(pool, s->arch);
+      str = pool_id2str(pool, s->arch);
       if (!strncmp(dir, str, l) && !str[l])
        repodata_set_void(data, solvid, SOLVABLE_MEDIADIR);
       else if (!dir[l])
@@ -2185,7 +2189,7 @@ repodata_set_location(Repodata *data, Id solvid, int medianr, const char *dir, c
        }
     }
   fp = file;
-  str = id2str(pool, s->name);
+  str = pool_id2str(pool, s->name);
   l = strlen(str);
   if ((!l || !strncmp(fp, str, l)) && fp[l] == '-')
     {
@@ -2195,7 +2199,7 @@ repodata_set_location(Repodata *data, Id solvid, int medianr, const char *dir, c
       if ((!l || !strncmp(fp, str, l)) && fp[l] == '.')
        {
          fp += l + 1;
-         str = id2str(pool, s->arch);
+         str = pool_id2str(pool, s->arch);
          l = strlen(str);
          if ((!l || !strncmp(fp, str, l)) && !strcmp(fp + l, ".rpm"))
            {
@@ -2208,6 +2212,23 @@ repodata_set_location(Repodata *data, Id solvid, int medianr, const char *dir, c
 }
 
 void
+repodata_set_idarray(Repodata *data, Id solvid, Id keyname, Queue *q)
+{
+  Repokey key;
+  int i;
+
+  key.name = keyname;
+  key.type = REPOKEY_TYPE_IDARRAY;
+  key.size = 0;
+  key.storage = KEY_STORAGE_INCORE;
+  repodata_set(data, solvid, &key, data->attriddatalen);
+  data->attriddata = sat_extend(data->attriddata, data->attriddatalen, q->count + 1, sizeof(Id), REPODATA_ATTRIDDATA_BLOCK);
+  for (i = 0; i < q->count; i++)
+    data->attriddata[data->attriddatalen++] = q->elements[i];
+  data->attriddata[data->attriddatalen++] = 0;
+}
+
+void
 repodata_add_dirnumnum(Repodata *data, Id solvid, Id keyname, Id dir, Id num, Id num2)
 {
   assert(dir);
@@ -2262,7 +2283,7 @@ repodata_add_poolstr_array(Repodata *data, Id solvid, Id keyname,
   if (data->localpool)
     id = stringpool_str2id(&data->spool, str, 1);
   else
-    id = str2id(data->repo->pool, str, 1);
+    id = pool_str2id(data->repo->pool, str, 1);
   repodata_add_idarray(data, solvid, keyname, id);
 }
 
@@ -2395,14 +2416,14 @@ data_addblob(struct extdata *xd, unsigned char *blob, int len)
 
 /*********************************/
 
+/* internalalize some key into incore/vincore data */
+
 static void
 repodata_serialize_key(Repodata *data, struct extdata *newincore,
                       struct extdata *newvincore,
                       Id *schema,
                       Repokey *key, Id val)
 {
-  /* Otherwise we have a new value.  Parse it into the internal
-     form.  */
   Id *ida;
   struct extdata *xd;
   unsigned int oldvincorelen = 0;
@@ -2470,21 +2491,13 @@ repodata_serialize_key(Repodata *data, struct extdata *newincore,
        schemaid = 0;
        for (ida = data->attriddata + val; *ida; ida++)
          {
-#if 0
-           fprintf(stderr, "serialize struct %d\n", *ida);
-#endif
            sp = schema;
            Id *kp = data->xattrs[-*ida];
            if (!kp)
              continue;
            num++;
            for (;*kp; kp += 2)
-             {
-#if 0
-               fprintf(stderr, "  %s:%d\n", id2str(data->repo->pool, data->keys[*kp].name), kp[1]);
-#endif
-               *sp++ = *kp;
-             }
+             *sp++ = *kp;
            *sp = 0;
            if (!schemaid)
              schemaid = repodata_schema2id(data, schema, 1);
@@ -2493,9 +2506,6 @@ repodata_serialize_key(Repodata *data, struct extdata *newincore,
                pool_debug(data->repo->pool, SAT_FATAL, "fixarray substructs with different schemas\n");
                exit(1);
              }
-#if 0
-           fprintf(stderr, "  schema %d\n", schemaid);
-#endif
          }
        if (!num)
          break;
@@ -2507,10 +2517,7 @@ repodata_serialize_key(Repodata *data, struct extdata *newincore,
            if (!kp)
              continue;
            for (;*kp; kp += 2)
-             {
-               repodata_serialize_key(data, newincore, newvincore,
-                                      schema, data->keys + *kp, kp[1]);
-             }
+             repodata_serialize_key(data, newincore, newvincore, schema, data->keys + *kp, kp[1]);
          }
        break;
       }
@@ -2536,10 +2543,7 @@ repodata_serialize_key(Repodata *data, struct extdata *newincore,
            data_addid(xd, schemaid);
            kp = data->xattrs[-*ida];
            for (;*kp; kp += 2)
-             {
-               repodata_serialize_key(data, newincore, newvincore,
-                                      schema, data->keys + *kp, kp[1]);
-             }
+             repodata_serialize_key(data, newincore, newvincore, schema, data->keys + *kp, kp[1]);
          }
        break;
       }
@@ -2696,7 +2700,7 @@ fprintf(stderr, "schemadata %p\n", data->schemadata);
            }
          key = data->keys + *keyp;
 #if 0
-         fprintf(stderr, "internalize %d(%d):%s:%s\n", entry, entry + data->start, id2str(data->repo->pool, key->name), id2str(data->repo->pool, key->type));
+         fprintf(stderr, "internalize %d(%d):%s:%s\n", entry, entry + data->start, pool_id2str(data->repo->pool, key->name), pool_id2str(data->repo->pool, key->type));
 #endif
          ndp = dp;
          if (oldcount)
@@ -2774,7 +2778,8 @@ repodata_load_stub(Repodata *data)
 {
   Repo *repo = data->repo;
   Pool *pool = repo->pool;
-  int r;
+  int r, i;
+  struct _Pool_tmpspace oldtmpspace;
 
   if (!pool->loadcallback)
     {
@@ -2782,7 +2787,18 @@ repodata_load_stub(Repodata *data)
       return;
     }
   data->state = REPODATA_LOADING;
+
+  /* save tmp space */
+  oldtmpspace = pool->tmpspace;
+  memset(&pool->tmpspace, 0, sizeof(pool->tmpspace));
+
   r = pool->loadcallback(pool, data, pool->loadcallbackdata);
+
+  /* restore tmp space */
+  for (i = 0; i < POOL_TMPSPACEBUF; i++)
+    sat_free(pool->tmpspace.buf[i]);
+  pool->tmpspace = oldtmpspace;
+
   data->state = r ? REPODATA_AVAILABLE : REPODATA_ERROR;
 }