- move known id definitions to one file, lets see if g++ likes it
[platform/upstream/libsolv.git] / src / repodata.c
index 60fc61f..f974837 100644 (file)
@@ -37,6 +37,27 @@ extern unsigned int unchecked_decompress_buf (const unsigned char *in,
 
 #define REPODATA_BLOCK 255
 
+
+void
+repodata_init(Repodata *data, Repo *repo, int localpool)
+{
+  memset(data, 0, sizeof (*data));
+  data->repo = repo;
+  data->localpool = localpool;
+  if (localpool)
+    stringpool_init_empty(&data->spool);
+  data->keys = sat_calloc(1, sizeof(Repokey));
+  data->nkeys = 1;
+  data->schemata = sat_calloc(1, sizeof(Id));
+  data->schemadata = sat_calloc(1, sizeof(Id));
+  data->nschemata = 1;
+  data->schemadatalen = 1;
+  data->start = repo->start;
+  data->end = repo->end;
+  data->incoreoffset = sat_extend_resize(0, data->end - data->start, sizeof(Id), REPODATA_BLOCK);
+  data->pagefd = -1;
+}
+
 void
 repodata_free(Repodata *data)
 {
@@ -65,19 +86,21 @@ repodata_free(Repodata *data)
   sat_free(data->attrdata);
   sat_free(data->attriddata);
   
+  sat_free(data->location);
+
   if (data->pagefd != -1)
     close(data->pagefd);
 }
 
 static unsigned char *
-forward_to_key(Repodata *data, Id key, Id schemaid, unsigned char *dp)
+forward_to_key(Repodata *data, Id keyid, Id schemaid, unsigned char *dp)
 {
   Id k, *keyp;
 
   keyp = data->schemadata + data->schemata[schemaid];
   while ((k = *keyp++) != 0)
     {
-      if (k == key)
+      if (k == keyid)
        return dp;
       if (data->keys[k].storage == KEY_STORAGE_VERTICAL_OFFSET)
        {
@@ -113,6 +136,9 @@ load_page_range(Repodata *data, unsigned int pstart, unsigned int pend)
   if (i > pend)
     return data->blob_store + data->pages[pstart].mapped_at;
 
+  if (data->pagefd == -1)
+    return 0;
+
   /* Ensure that we can map the numbers of pages we need at all.  */
   if (pend - pstart + 1 > data->ncanmap)
     {
@@ -255,7 +281,7 @@ static unsigned char *
 make_vertical_available(Repodata *data, Repokey *key, Id off, Id len)
 {
   unsigned char *dp;
-  if (key->type == REPOKEY_TYPE_VOID)
+  if (!len)
     return 0;
   if (off >= data->lastverticaloffset)
     {
@@ -264,12 +290,11 @@ make_vertical_available(Repodata *data, Repokey *key, Id off, Id len)
        return 0;
       return data->vincore + off;
     }
-  if (data->pagefd == -1)
-    return 0;
   if (off + len > key->size)
     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 = load_page_range(data, off / BLOB_PAGESIZE, (off + len - 1) / BLOB_PAGESIZE);
   if (dp)
     dp += off % BLOB_PAGESIZE;
@@ -301,12 +326,33 @@ get_data(Repodata *data, Repokey *key, unsigned char **dpp)
 }
 
 static inline int
-maybe_load_repodata(Repodata *data)
+maybe_load_repodata(Repodata *data, Id *keyid)
 {
   if (data->state == REPODATA_STUB)
     {
       if (data->loadcallback)
-       data->loadcallback(data);
+       {
+         if (keyid)
+           {
+             /* key order may change when loading */
+             int i;
+             Id name = data->keys[*keyid].name;
+             Id type = data->keys[*keyid].type;
+             data->loadcallback(data);
+             if (data->state == REPODATA_AVAILABLE)
+               {
+                 for (i = 1; i < data->nkeys; i++)
+                   if (data->keys[i].name == name && data->keys[i].type == type)
+                     break;
+                 if (i < data->nkeys)
+                   *keyid = i;
+                 else
+                   return 0;
+               }
+           }
+         else
+           data->loadcallback(data);
+       }
       else
        data->state = REPODATA_ERROR;
     }
@@ -324,7 +370,7 @@ repodata_lookup_str(Repodata *data, Id entry, Id keyid)
   Id id, *keyp;
   unsigned char *dp;
 
-  if (!maybe_load_repodata (data))
+  if (!maybe_load_repodata(data, &keyid))
     return 0;
 
   dp = data->incoredata + data->incoreoffset[entry];
@@ -352,7 +398,7 @@ repodata_lookup_str(Repodata *data, Id entry, Id keyid)
 }
 
 int
-repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned *value)
+repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned int *value)
 {
   Id schema;
   Repokey *key;
@@ -362,7 +408,7 @@ repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned *value)
 
   *value = 0;
 
-  if (!maybe_load_repodata (data))
+  if (!maybe_load_repodata(data, &keyid))
     return 0;
 
   dp = data->incoredata + data->incoreoffset[entry];
@@ -387,6 +433,22 @@ repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned *value)
   return 0;
 }
 
+int
+repodata_lookup_void(Repodata *data, Id entry, Id keyid)
+{
+  Id schema;
+  Id *keyp;
+  unsigned char *dp;
+  if (!maybe_load_repodata(data, &keyid))
+    return 0;
+  dp = data->incoredata + data->incoreoffset[entry];
+  dp = data_read_id(dp, &schema);
+  for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
+    if (!*keyp)
+      return 0;
+  return 1;
+}
+
 void
 repodata_search(Repodata *data, Id entry, Id keyname, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata)
 {
@@ -398,7 +460,7 @@ repodata_search(Repodata *data, Id entry, Id keyname, int (*callback)(void *cbda
   int stop;
   KeyValue kv;
 
-  if (!maybe_load_repodata (data))
+  if (!maybe_load_repodata(data, 0))
     return;
 
   dp = data->incoredata + data->incoreoffset[entry];
@@ -767,26 +829,6 @@ weg2:
   return 1;
 }
 
-void
-repodata_init(Repodata *data, Repo *repo, int localpool)
-{
-  memset(data, 0, sizeof (*data));
-  data->repo = repo;
-  data->localpool = localpool;
-  if (localpool)
-    stringpool_init_empty(&data->spool);
-  data->keys = sat_calloc(1, sizeof(Repokey));
-  data->nkeys = 1;
-  data->schemata = sat_calloc(1, sizeof(Id));
-  data->schemadata = sat_calloc(1, sizeof(Id));
-  data->nschemata = 1;
-  data->schemadatalen = 1;
-  data->start = repo->start;
-  data->end = repo->end;
-  data->incoreoffset = sat_extend_resize(0, data->end - data->start, sizeof(Id), REPODATA_BLOCK);
-  data->pagefd = -1;
-}
-
 /* extend repodata so that it includes solvables p */
 void
 repodata_extend(Repodata *data, Id p)
@@ -830,8 +872,7 @@ repodata_extend_block(Repodata *data, Id start, Id num)
     return;
   if (!data->incoreoffset)
     {
-      data->incoreoffset = sat_extend_resize(data->incoreoffset, num, sizeof(Id), REPODATA_BLOCK);
-      memset(data->incoreoffset, 0, num * sizeof(Id));
+      data->incoreoffset = sat_calloc_block(num, sizeof(Id), REPODATA_BLOCK);
       data->start = start;
       data->end = start + num;
       return;
@@ -841,6 +882,8 @@ repodata_extend_block(Repodata *data, Id start, Id num)
     repodata_extend(data, start + num - 1);
 }
 
+/**********************************************************************/
+
 #define REPODATA_ATTRS_BLOCK 63
 #define REPODATA_ATTRDATA_BLOCK 1023
 #define REPODATA_ATTRIDDATA_BLOCK 63
@@ -852,8 +895,8 @@ repodata_insert_keyid(Repodata *data, Id entry, Id keyid, Id val, int overwrite)
   int i;
   if (!data->attrs)
     {
-      data->attrs = sat_extend_resize(0, data->end - data->start, sizeof(Id *), REPODATA_BLOCK);
-      memset(data->attrs, 0, (data->end - data->start) * sizeof(Id *));
+      data->attrs = sat_calloc_block(data->end - data->start, sizeof(Id *),
+                                    REPODATA_BLOCK);
     }
   i = 0;
   if (data->attrs[entry])
@@ -1106,10 +1149,12 @@ fprintf(stderr, "repodata_add_dirstr %d %d %s (%d)\n", entry, dir, str,  data->a
 }
 
 void
-repodata_merge_attrs (Repodata *data, Id dest, Id src)
+repodata_merge_attrs(Repodata *data, Id dest, Id src)
 {
   Id *keyp;
-  for (keyp = data->attrs[src]; *keyp; keyp += 2)
+  if (dest == src || !(keyp = data->attrs[src]))
+    return;
+  for (; *keyp; keyp += 2)
     repodata_insert_keyid(data, dest, keyp[0], keyp[1], 0);
 }
 
@@ -1418,6 +1463,8 @@ repodata_str2dir(Repodata *data, const char *dir, int create)
   parent = 0;
   while (*dir == '/' && dir[1] == '/')
     dir++;
+  if (*dir == '/' && !dir[1])
+    return 1;
   while (*dir)
     {
       dire = strchrnul(dir, '/');
@@ -1439,6 +1486,52 @@ repodata_str2dir(Repodata *data, const char *dir, int create)
   return parent;
 }
 
+const char *
+repodata_dir2str(Repodata *data, Id did, const char *suf)
+{
+  Pool *pool = data->repo->pool;
+  int l = 0;
+  Id parent, comp;
+  const char *comps;
+  char *p;
+
+  if (!did)
+    return suf ? suf : "";
+  parent = did;
+  while (parent)
+    {
+      comp = dirpool_compid(&data->dirpool, parent);
+      comps = stringpool_id2str(data->localpool ? &data->spool : &pool->ss, comp);
+      l += strlen(comps);
+      parent = dirpool_parent(&data->dirpool, parent);
+      if (parent)
+       l++;
+    }
+  if (suf)
+    l += strlen(suf) + 1;
+  p = pool_alloctmpspace(pool, l + 1) + l;
+  *p = 0;
+  if (suf)
+    {
+      p -= strlen(suf);
+      strcpy(p, suf);
+      *--p = '/';
+    }
+  parent = did;
+  while (parent)
+    {
+      comp = dirpool_compid(&data->dirpool, parent);
+      comps = stringpool_id2str(data->localpool ? &data->spool : &pool->ss, comp);
+      l = strlen(comps);
+      p -= l;
+      strncpy(p, comps, l);
+      parent = dirpool_parent(&data->dirpool, parent);
+      if (parent)
+        *--p = '/';
+    }
+  return p;
+}
+
 unsigned int
 repodata_compress_page(unsigned char *page, unsigned int len, unsigned char *cpage, unsigned int max)
 {
@@ -1561,6 +1654,13 @@ repodata_read_or_setup_pages(Repodata *data, unsigned int pagesz, unsigned int b
     }
 }
 
+void
+repodata_disable_paging(Repodata *data)
+{
+  if (maybe_load_repodata(data, 0)
+      && data->num_pages)
+    load_page_range (data, 0, data->num_pages - 1);
+}
 /*
 vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4:
 */