]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Working but for now inactive code to support non-solvables (things which
authorMichael Matz <matz@suse.de>
Tue, 1 Apr 2008 22:24:07 +0000 (22:24 +0000)
committerMichael Matz <matz@suse.de>
Tue, 1 Apr 2008 22:24:07 +0000 (22:24 +0000)
have attributes, but are not solvables).  The usual functions interpret
negative entry numbers as those (positive ones are solvable IDs).  I'll
probably refine the code some more, hence it's work in progress.

susetags2repo: Parse also a "=Lan:" tag, which can be injected
externally when multiple language tag files are catted together.

src/pooltypes.h
src/repo.c
src/repo.h
src/repo_solv.c
src/repodata.c
src/repodata.h
tools/dumpsolv.c
tools/repo_susetags.c
tools/repo_write.c

index cfe837d480d33a1bca32e38c1c2fba7e3f225660..836bc9ba1a048cd78fef2a1f1b4076a35cebfa80 100644 (file)
@@ -21,6 +21,7 @@
 #define SOLV_VERSION_4 4
 #define SOLV_VERSION_5 5
 #define SOLV_VERSION_6 6
+#define SOLV_VERSION_7 7
 
 #define SOLV_FLAG_PREFIX_POOL 4
 
index e147cfbda87d8d0809d231eabe49f9178bc6102f..fc7229bf3af2c1a37f093d0216585e21436aec97 100644 (file)
@@ -595,8 +595,8 @@ repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md)
   KeyValue kv;
   Pool *pool = repo->pool;
   Repodata *data;
-  Solvable *s;
   int i, j, flags;
+  Solvable *s;
 
   md->stop = 0;
   if (!p)
@@ -610,10 +610,14 @@ repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md)
        }
       return;
     }
-  s = pool->solvables + p;
+  else if (p < 0)
+    /* The callback only supports solvables, so we can't iterate over the
+       extra things.  */
+    return;
   flags = md->flags;
   if (!(flags & SEARCH_NO_STORAGE_SOLVABLE))
     {
+      s = pool->solvables + p;
       switch(keyname)
        {
          case 0:
@@ -868,8 +872,26 @@ repo_findrepodata(Repo *repo, Id p, Id keyname)
 
   /* FIXME: enter nice code here */
   for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
-    if (p >= data->start && p < data->end)
+    if ((p < 0 && (-1 - p) >= data->extrastart && (-1 - p) < (data->extrastart + data->nextra))
+       || (p >= 0 && p >= data->start && p < data->end))
+      return data;
+  if (p < 0)
+    {
+      data = repo->repodata;
+      if (data)
+       {
+         for (i = 1; i < repo->nrepodata; i++)
+           if (data->extrastart + data->nextra
+               > repo->repodata[i].extrastart + repo->repodata[i].nextra)
+             data = repo->repodata + i;
+       }
+      else
+       data = repo_add_repodata(repo, 0);
+      repodata_extend_extra(data, (-1 - p) - data->extrastart + 1);
+      if (-p > repo->nextra)
+       repo->nextra = -p;
       return data;
+    }
   for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
     if (p == data->end)
       break;
@@ -885,28 +907,45 @@ void
 repo_set_id(Repo *repo, Id p, Id keyname, Id id)
 {
   Repodata *data = repo_findrepodata(repo, p, keyname);
-  repodata_set_id(data, p - data->start, keyname, id);
+  if (p < 0)
+    /* This is -1 - ((-1 - p) - data->extrastart).  */
+    p = p + data->extrastart;
+  else
+    p = p - data->start;
+  repodata_set_id(data, p, keyname, id);
 }
 
 void
 repo_set_num(Repo *repo, Id p, Id keyname, Id num)
 {
   Repodata *data = repo_findrepodata(repo, p, keyname);
-  repodata_set_num(data, p - data->start, keyname, num);
+  if (p < 0)
+    p = p + data->extrastart;
+  else
+    p = p - data->start;
+  repodata_set_num(data, p, keyname, num);
 }
 
 void
 repo_set_str(Repo *repo, Id p, Id keyname, const char *str)
 {
   Repodata *data = repo_findrepodata(repo, p, keyname);
-  repodata_set_str(data, p - data->start, keyname, str);
+  if (p < 0)
+    p = p + data->extrastart;
+  else
+    p = p - data->start;
+  repodata_set_str(data, p, keyname, str);
 }
 
 void
 repo_set_poolstr(Repo *repo, Id p, Id keyname, const char *str)
 {
   Repodata *data = repo_findrepodata(repo, p, keyname);
-  repodata_set_poolstr(data, p - data->start, keyname, str);
+  if (p < 0)
+    p = p + data->extrastart;
+  else
+    p = p - data->start;
+  repodata_set_poolstr(data, p, keyname, str);
 }
 
 void
@@ -916,7 +955,7 @@ repo_internalize(Repo *repo)
   Repodata *data;
 
   for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
-    if (data->attrs)
+    if (data->attrs || data->extraattrs)
       repodata_internalize(data);
 }
 
index 26618355470ad51479e5310d808b6d8190f33833..07dc68761293a73ccaa9fcc27942df4adff0abba 100644 (file)
@@ -40,6 +40,7 @@ typedef struct _Repo {
   int start;                   /* start of this repo solvables within pool->solvables */
   int end;                     /* last solvable + 1 of this repo */
   int nsolvables;              /* number of solvables repo is contributing to pool */
+  int nextra;                  /* number of extra objects (non-solvables) */
 
   int priority;                        /* priority of this repo */
 
@@ -155,6 +156,7 @@ typedef struct _KeyValue {
 
 #define        SEARCH_NOCASE                   (1<<8)
 #define        SEARCH_NO_STORAGE_SOLVABLE      (1<<9)
+#define SEARCH_EXTRA                   (1<<10)
 
 /* Internal */
 #define __SEARCH_ONESOLVABLE           (1 << 31)
index 9ede7d3fd9df8b14ded12f47ab96cac52202caef..119a0db6ffdcc3c94f5ce037aff3ec8a81771055 100644 (file)
@@ -722,7 +722,7 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
   Pool *pool = repo->pool;
   int i, l;
   unsigned int numid, numrel, numdir, numsolv;
-  unsigned int numkeys, numschemata, numinfo;
+  unsigned int numkeys, numschemata, numinfo, numextra;
 
   Offset sizeid;
   Offset *str;                        /* map Id -> Offset into string space */
@@ -772,6 +772,8 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
     {
       case SOLV_VERSION_6:
         break;
+      case SOLV_VERSION_7:
+       break;
       default:
         pool_debug(pool, SAT_ERROR, "unsupported SOLV version\n");
         return SOLV_ERROR_UNSUPPORTED;
@@ -786,6 +788,10 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
   numkeys = read_u32(&data);
   numschemata = read_u32(&data);
   numinfo = read_u32(&data);
+  if (solvversion > SOLV_VERSION_6)
+    numextra = read_u32(&data);
+  else
+    numextra = 0;
   solvflags = read_u32(&data);
 
   if (numdir && numdir < 2)
@@ -806,6 +812,11 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
          pool_debug(pool, SAT_ERROR, "unequal number of solvables in a store\n");
          return SOLV_ERROR_CORRUPT;
        }
+      if (parent->nextra != numextra)
+       {
+         pool_debug(pool, SAT_ERROR, "unequal number of non-solvables in a store\n");
+         return SOLV_ERROR_CORRUPT;
+       }
       if (numinfo)
        {
          pool_debug(pool, SAT_ERROR, "info blocks are forbidden in a store\n");
@@ -1225,7 +1236,7 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
        size_idarray += keys[i].size;
     }
 
-  if (numsolv)
+  if (numsolv || numextra)
     {
       maxsize = read_id(&data, 0);
       allsize = read_id(&data, 0);
@@ -1267,6 +1278,18 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
   else
     s = 0;
 
+  if (numextra)
+    {
+      data.extrastart = repo->nextra;
+      repodata_extend_extra(&data, numextra);
+      repo->nextra += numextra;
+      for (i = oldnrepodata; i < repo->nrepodata; i++)
+        {
+         repo->repodata[i].extrastart = data.extrastart;
+         repo->repodata[i].nextra = data.nextra;
+       }
+    }
+
   if (have_xdata)
     {
       /* reserve one byte so that all offsets are not zero */
@@ -1277,7 +1300,7 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
   left = 0;
   buf = sat_calloc(maxsize + 4, 1);
   dp = buf;
-  for (i = 0; i < numsolv; i++, s++)
+  for (i = 0; i < numsolv + numextra; i++, s++)
     {
       Id *keyp;
       if (data.error)
@@ -1308,9 +1331,20 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
       dp = data_read_id_max(dp, &id, 0, numschemata, &data.error);
       if (have_xdata)
        {
-         data.incoreoffset[i] = data.incoredatalen;
+         if (i < numsolv)
+           data.incoreoffset[i] = data.incoredatalen;
+         else
+           data.extraoffset[i - numsolv] = data.incoredatalen;
          incore_add_id(&data, id);
        }
+      if (i >= numsolv)
+       s = 0;
+#if 0
+      if (i < numsolv)
+       fprintf(stderr, "solv %d: schema %d\n", i, id);
+      else
+       fprintf(stderr, "extra %d: schema %d\n", i - numsolv, id);
+#endif
       keyp = schemadata + schemata[id];
       while ((key = *keyp++) != 0)
        {
@@ -1319,7 +1353,10 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
 
          id = keys[key].name;
 #if 0
-fprintf(stderr, "solv %d name %d type %d class %d\n", i, id, keys[key].type, keys[key].storage);
+         if (i < numsolv)
+           fprintf(stderr, "solv %d name %d type %d class %d\n", i, id, keys[key].type, keys[key].storage);
+         else
+           fprintf(stderr, "extra %d name %d type %d class %d\n", i - numsolv, id, keys[key].type, keys[key].storage);
 #endif
          if (keys[key].storage == KEY_STORAGE_VERTICAL_OFFSET)
            {
index ddcc7674f6b9309d7dd74f1c341ff942fa4a61f0..ea4b39968224e960bad3e1f63c63c045b57023ea 100644 (file)
@@ -54,7 +54,10 @@ repodata_init(Repodata *data, Repo *repo, int localpool)
   data->schemadatalen = 1;
   data->start = repo->start;
   data->end = repo->end;
+  data->nextra = repo->nextra;
+  data->extrastart = 0;
   data->incoreoffset = sat_extend_resize(0, data->end - data->start, sizeof(Id), REPODATA_BLOCK);
+  data->extraoffset = sat_extend_resize(0, repo->nextra, sizeof(Id), REPODATA_BLOCK);
   data->pagefd = -1;
 }
 
@@ -74,6 +77,7 @@ repodata_free(Repodata *data)
 
   sat_free(data->incoredata);
   sat_free(data->incoreoffset);
+  sat_free(data->extraoffset);
   sat_free(data->verticaloffset);
 
   sat_free(data->blob_store);
@@ -83,6 +87,7 @@ repodata_free(Repodata *data)
   sat_free(data->vincore);
 
   sat_free(data->attrs);
+  sat_free(data->extraattrs);
   sat_free(data->attrdata);
   sat_free(data->attriddata);
   
@@ -363,6 +368,15 @@ maybe_load_repodata(Repodata *data, Id *keyid)
   return 0;
 }
 
+static inline unsigned char*
+entry2data(Repodata *data, Id entry)
+{
+  if (entry < 0)
+    return data->incoredata + data->extraoffset[-1 - entry];
+  else
+    return data->incoredata + data->incoreoffset[entry];
+}
+
 Id
 repodata_lookup_id(Repodata *data, Id entry, Id keyid)
 {
@@ -373,7 +387,7 @@ repodata_lookup_id(Repodata *data, Id entry, Id keyid)
 
   if (!maybe_load_repodata(data, &keyid))
     return 0;
-  dp = data->incoredata + data->incoreoffset[entry];
+  dp = entry2data(data, entry);
   dp = data_read_id(dp, &schema);
   /* make sure the schema of this solvable contains the key */
   for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
@@ -403,7 +417,7 @@ repodata_lookup_str(Repodata *data, Id entry, Id keyid)
   if (!maybe_load_repodata(data, &keyid))
     return 0;
 
-  dp = data->incoredata + data->incoreoffset[entry];
+  dp = entry2data(data, entry);
   dp = data_read_id(dp, &schema);
   /* make sure the schema of this solvable contains the key */
   for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
@@ -441,7 +455,7 @@ repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned int *value)
   if (!maybe_load_repodata(data, &keyid))
     return 0;
 
-  dp = data->incoredata + data->incoreoffset[entry];
+  dp = entry2data(data, entry);
   dp = data_read_id(dp, &schema);
   /* make sure the schema of this solvable contains the key */
   for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
@@ -471,7 +485,7 @@ repodata_lookup_void(Repodata *data, Id entry, Id keyid)
   unsigned char *dp;
   if (!maybe_load_repodata(data, &keyid))
     return 0;
-  dp = data->incoredata + data->incoreoffset[entry];
+  dp = entry2data(data, entry);
   dp = data_read_id(dp, &schema);
   for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
     if (!*keyp)
@@ -489,7 +503,7 @@ repodata_lookup_bin_checksum(Repodata *data, Id entry, Id keyid, Id *typep)
 
   if (!maybe_load_repodata(data, &keyid))
     return 0;
-  dp = data->incoredata + data->incoreoffset[entry];
+  dp = entry2data(data, entry);
   dp = data_read_id(dp, &schema);
   for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
     if (!*keyp)
@@ -511,10 +525,11 @@ repodata_search(Repodata *data, Id entry, Id keyname, int (*callback)(void *cbda
   int stop;
   KeyValue kv;
 
-  if (!maybe_load_repodata(data, 0))
+  if (entry < 0
+      || !maybe_load_repodata(data, 0))
     return;
 
-  dp = data->incoredata + data->incoreoffset[entry];
+  dp = entry2data(data, entry);
   dp = data_read_id(dp, &schema);
   keyp = data->schemadata + data->schemata[schema];
   if (keyname)
@@ -577,7 +592,11 @@ dataiterator_newdata(Dataiterator *di)
     return;
 
   Id schema;
-  unsigned char *dp = data->incoredata + data->incoreoffset[di->solvid - data->start];
+  unsigned char *dp = data->incoredata;
+  if (di->solvid >= 0)
+    dp += data->incoreoffset[di->solvid - data->start];
+  else
+    dp += data->extraoffset[-1 - di->solvid - data->extrastart];
   dp = data_read_id(dp, &schema);
   Id *keyp = data->schemadata + data->schemata[schema];
   if (keyname)
@@ -626,6 +645,11 @@ dataiterator_init(Dataiterator *di, Repo *repo, Id p, Id keyname,
   else
     {
       di->solvid = repo->start - 1;
+      if (di->solvid < 0)
+       {
+         fprintf(stderr, "A repo contains the NULL solvable!\n");
+         exit(1);
+       }
       di->data = repo->repodata + repo->nrepodata - 1;
       di->state = 0;
     }
@@ -843,20 +867,37 @@ restart:
                        {
                          if (di->flags & __SEARCH_ONESOLVABLE)
                            return 0;
-                         while (++di->solvid < repo->end)
-                           if (repo->pool->solvables[di->solvid].repo == repo)
-                             break;
-                         if (di->solvid >= repo->end)
-                           return 0;
+                         if (di->solvid >= 0)
+                           {
+                             while (++di->solvid < repo->end)
+                               if (repo->pool->solvables[di->solvid].repo == repo)
+                                 break;
+                             if (di->solvid >= repo->end)
+                               {
+                                 if (!(di->flags & SEARCH_EXTRA))
+                                   return 0;
+                                 di->solvid = -1;
+                                 if (di->solvid < -repo->nextra)
+                                   return 0;
+                               }
+                           }
+                         else
+                           {
+                             --di->solvid;
+                             if (di->solvid < -repo->nextra)
+                               return 0;
+                           }
                          di->data = repo->repodata - 1;
-                         if (di->flags & SEARCH_NO_STORAGE_SOLVABLE)
+                         if (di->solvid < 0
+                             || (di->flags & SEARCH_NO_STORAGE_SOLVABLE))
                            continue;
                          static Id zeroid = 0;
                          di->keyp = &zeroid;
                          di->state = 1;
                          goto restart;
                        }
-                     if (di->solvid >= data->start && di->solvid < data->end)
+                     if ((di->solvid < 0 && (-1 - di->solvid) >= data->extrastart && (-1 - di->solvid) < (data->extrastart + data->nextra))
+                         || (di->solvid >= 0 && di->solvid >= data->start && di->solvid < data->end))
                        {
                          dataiterator_newdata(di);
                          if (di->nextkeydp)
@@ -916,6 +957,21 @@ repodata_extend(Repodata *data, Id p)
     }
 }
 
+void
+repodata_extend_extra(Repodata *data, int nextra)
+{
+  if (nextra <= data->nextra)
+    return;
+  if (data->extraattrs)
+    {
+      data->extraattrs = sat_extend(data->extraattrs, data->nextra, nextra - data->nextra, sizeof(Id *), REPODATA_BLOCK);
+      memset(data->extraattrs + data->nextra, 0, (nextra - data->nextra) * sizeof (Id *));
+    }
+  data->extraoffset = sat_extend(data->extraoffset, data->nextra, nextra - data->nextra, sizeof(Id), REPODATA_BLOCK);
+  memset(data->extraoffset + data->nextra, 0, (nextra - data->nextra) * sizeof(Id));
+  data->nextra = nextra;
+}
+
 void
 repodata_extend_block(Repodata *data, Id start, Id num)
 {
@@ -943,16 +999,23 @@ static void
 repodata_insert_keyid(Repodata *data, Id entry, Id keyid, Id val, int overwrite)
 {
   Id *pp;
+  Id *ap;
   int i;
-  if (!data->attrs)
+  if (!data->attrs && entry >= 0)
     {
       data->attrs = sat_calloc_block(data->end - data->start, sizeof(Id *),
                                     REPODATA_BLOCK);
     }
+  else if (!data->extraattrs && entry < 0)
+    data->extraattrs = sat_calloc_block(data->nextra, sizeof(Id *), REPODATA_BLOCK);
+  if (entry < 0)
+    ap = data->extraattrs[-1 - entry];
+  else
+    ap = data->attrs[entry];
   i = 0;
-  if (data->attrs[entry])
+  if (ap)
     {
-      for (pp = data->attrs[entry]; *pp; pp += 2)
+      for (pp = ap; *pp; pp += 2)
        /* Determine equality based on the name only, allows us to change
           type (when overwrite is set), and makes TYPE_CONSTANT work.  */
         if (data->keys[*pp].name == data->keys[keyid].name)
@@ -966,10 +1029,14 @@ repodata_insert_keyid(Repodata *data, Id entry, Id keyid, Id val, int overwrite)
            }
           return;
         }
-      i = pp - data->attrs[entry];
+      i = pp - ap;
     }
-  data->attrs[entry] = sat_extend(data->attrs[entry], i, 3, sizeof(Id), REPODATA_ATTRS_BLOCK);
-  pp = data->attrs[entry] + i;
+  ap = sat_extend(ap, i, 3, sizeof(Id), REPODATA_ATTRS_BLOCK);
+  if (entry < 0)
+    data->extraattrs[-1 - entry] = ap;
+  else
+    data->attrs[entry] = ap;
+  pp = ap + i;
   *pp++ = keyid;
   *pp++ = val;
   *pp = 0;
@@ -1096,9 +1163,12 @@ repoadata_add_array(Repodata *data, Id entry, Id keyname, Id keytype, int entrys
   int oldsize;
   Id *ida, *pp;
 
-  pp = 0;
-  if (data->attrs && data->attrs[entry])
-    for (pp = data->attrs[entry]; *pp; pp += 2)
+  if (entry < 0)
+    pp = data->extraattrs ? data->extraattrs[-1 - entry] : 0;
+  else
+    pp = data->attrs ? data->attrs[entry] : 0;
+  if (pp)
+    for (; *pp; pp += 2)
       if (data->keys[*pp].name == keyname && data->keys[*pp].type == keytype)
         break;
   if (!pp || !*pp)
@@ -1231,7 +1301,8 @@ repodata_chk2str(Repodata *data, Id type, const unsigned char *buf)
   return str;
 }
 
-Id repodata_globalize_id(Repodata *data, Id id)
+Id
+repodata_globalize_id(Repodata *data, Id id)
 { 
   if (!data || !data->localpool)
     return id;
@@ -1300,7 +1371,8 @@ void
 repodata_merge_attrs(Repodata *data, Id dest, Id src)
 {
   Id *keyp;
-  if (dest == src || !(keyp = data->attrs[src]))
+  if (dest == src
+      || !(keyp = src < 0 ? data->extraattrs[-1 - src] : data->attrs[src]))
     return;
   for (; *keyp; keyp += 2)
     repodata_insert_keyid(data, dest, keyp[0], keyp[1], 0);
@@ -1425,7 +1497,7 @@ repodata_internalize(Repodata *data)
   struct extdata newincore;
   struct extdata newvincore;
 
-  if (!data->attrs)
+  if (!data->attrs && !data->extraattrs)
     return;
 
   newvincore.buf = data->vincore;
@@ -1440,11 +1512,13 @@ repodata_internalize(Repodata *data)
   addschema_prepare(data, schematacache);
   memset(&newincore, 0, sizeof(newincore));
   data_addid(&newincore, 0);
-  for (entry = 0; entry < nentry; entry++)
+  if (!data->attrs)
+    nentry = 0;
+  for (entry = data->extraattrs ? -data->nextra : 0; entry < nentry; entry++)
     {
       memset(seen, 0, data->nkeys * sizeof(Id));
       sp = schema;
-      dp = data->incoredata + data->incoreoffset[entry];
+      dp = entry2data(data, entry);
       if (data->incoredata)
         dp = data_read_id(dp, &oldschema);
       else
@@ -1468,8 +1542,9 @@ fprintf(stderr, "schemadata %p\n", data->schemadata);
          *sp++ = *keyp;
          oldcount++;
        }
-      if (data->attrs[entry])
-        for (keyp = data->attrs[entry]; *keyp; keyp += 2)
+      keyp = entry < 0 ? data->extraattrs[-1 - entry] : data->attrs[entry];
+      if (keyp)
+        for (; *keyp; keyp += 2)
          {
            if (!seen[*keyp])
              {
@@ -1497,7 +1572,10 @@ fprintf(stderr, "schemadata %p\n", data->schemadata);
         (oX being the old keyids (possibly overwritten), and nX being
          the new keyids).  This rules out sorting the keyids in order
         to ensure a small schema count.  */
-      data->incoreoffset[entry] = newincore.len;
+      if (entry < 0)
+       data->extraoffset[-1 - entry] = newincore.len;
+      else
+       data->incoreoffset[entry] = newincore.len;
       data_addid(&newincore, schemaid);
       for (keyp = data->schemadata + data->schemata[schemaid]; *keyp; keyp++)
        {
@@ -1591,7 +1669,9 @@ fprintf(stderr, "schemadata %p\n", data->schemadata);
            }
          dp = ndp;
        }
-      if (data->attrs[entry])
+      if (entry < 0 && data->extraattrs[-1 - entry])
+       sat_free(data->extraattrs[-1 - entry]);
+      else if (entry >= 0 && data->attrs[entry])
         sat_free(data->attrs[entry]);
     }
   sat_free(schema);
@@ -1607,6 +1687,7 @@ fprintf(stderr, "schemadata %p\n", data->schemadata);
   data->vincorelen = newvincore.len;
 
   data->attrs = sat_free(data->attrs);
+  data->extraattrs = sat_free(data->extraattrs);
   data->attrdata = sat_free(data->attrdata);
   data->attriddata = sat_free(data->attriddata);
   data->attrdatalen = 0;
index 6139db9d67a197343e9b062cdc34689d5ea8712f..091390ca3657fd47eeba6e63c5fb20c344b1a605 100644 (file)
@@ -57,6 +57,8 @@ typedef struct _Repodata {
 
   int start;                   /* start of solvables this repodata is valid for */
   int end;                     /* last solvable + 1 of this repodata */
+  int extrastart;
+  int nextra;
 
   FILE *fp;                    /* file pointer of solv file */
   int error;                   /* corrupt solv file */
@@ -81,6 +83,7 @@ typedef struct _Repodata {
   unsigned int incoredatafree; /* free data len */
 
   Id *incoreoffset;            /* offset for all entries (ent2attr) */
+  Id *extraoffset;             /* offset for all extra entries */
 
   Id *verticaloffset;          /* offset for all verticals, nkeys elements */
   Id lastverticaloffset;       /* end of verticals */
@@ -100,6 +103,7 @@ typedef struct _Repodata {
   unsigned int vincorelen;
 
   Id **attrs;                  /* un-internalized attributes */
+  Id **extraattrs;             /* Same, but for extra objects.  */
   unsigned char *attrdata;     /* their string data space */
   unsigned int attrdatalen;
   Id *attriddata;              /* their id space */
@@ -111,6 +115,7 @@ typedef struct _Repodata {
 /* management functions */
 void repodata_init(Repodata *data, struct _Repo *repo, int localpool);
 void repodata_extend(Repodata *data, Id p);
+void repodata_extend_extra(Repodata *data, int nextra);
 void repodata_extend_block(Repodata *data, Id p, int num);
 void repodata_free(Repodata *data);
 
index 0c9816adfe8bffd11fa3da10335d8e505e98abf8..a6f5fe4b30ba94fd753d4a500118ac3d58db3fb0 100644 (file)
@@ -58,28 +58,28 @@ printids(Repo *repo, char *kind, Offset ido)
 }
 
 int
-dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
+dump_attr(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv)
 {
   const char *keyname;
 
-  keyname = id2str(s->repo->pool, key->name);
+  keyname = id2str(repo->pool, key->name);
   switch(key->type)
     {
     case REPOKEY_TYPE_ID:
       if (data && data->localpool)
        kv->str = stringpool_id2str(&data->spool, kv->id);
       else
-        kv->str = id2str(s->repo->pool, kv->id);
+        kv->str = id2str(repo->pool, kv->id);
       printf("%s: %s\n", keyname, kv->str);
       break;
     case REPOKEY_TYPE_CONSTANTID:
-      printf("%s: %s\n", keyname, dep2str(s->repo->pool, kv->id));
+      printf("%s: %s\n", keyname, dep2str(repo->pool, kv->id));
       break;
     case REPOKEY_TYPE_IDARRAY:
       if (data && data->localpool)
         printf("%s: %s\n", keyname, stringpool_id2str(&data->spool, kv->id));
       else
-        printf("%s: %s\n", keyname, dep2str(s->repo->pool, kv->id));
+        printf("%s: %s\n", keyname, dep2str(repo->pool, kv->id));
       break;
     case REPOKEY_TYPE_STR:
       printf("%s: %s\n", keyname, kv->str);
@@ -110,6 +110,12 @@ dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyV
   return 0;
 }
 
+static int
+dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
+{
+  return dump_attr(s->repo, data, key, kv);
+}
+
 /*
  * dump all attributes for Id <p>
  */
@@ -123,8 +129,7 @@ dump_repoattrs(Repo *repo, Id p)
   Dataiterator di;
   dataiterator_init(&di, repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE);
   while (dataiterator_step(&di))
-    dump_repoattrs_cb(0, repo->pool->solvables + di.solvid, di.data, di.key,
-                     &di.kv);
+    dump_attr(repo, di.data, di.key, &di.kv);
 #endif
 }
 
@@ -244,7 +249,7 @@ int main(int argc, char **argv)
     printf("could not read repository\n");
   printf("pool contains %d strings, %d rels, string size is %d\n", pool->ss.nstrings, pool->nrels, pool->ss.sstrings);
   dump_repodata(repo);
-  printf("repo contains %d solvables\n", repo->nsolvables);
+  printf("repo contains %d solvables %d non-solvables\n", repo->nsolvables, repo->nextra);
   for (i = repo->start, n = 1; i < repo->end; i++)
     {
       s = pool->solvables + i;
@@ -276,6 +281,14 @@ int main(int argc, char **argv)
 #endif
       n++;
     }
+  for (i = 0; i < repo->nextra; i++)
+    {
+      printf("\nextra %d:\n", i);
+      Dataiterator di;
+      dataiterator_init(&di, repo, -1 - i, 0, 0, SEARCH_EXTRA | SEARCH_NO_STORAGE_SOLVABLE);
+      while (dataiterator_step(&di))
+       dump_attr(repo, di.data, di.key, &di.kv);
+    }
 #if 0
   tryme(repo, 0, SOLVABLE_MEDIANR, 0, 0);
   printf("\n");
index 7443fdf6a986d1be909df068abd748cc886f7ed5..e9fd823117c6c07d70c690238d811582f2bfba2a 100644 (file)
@@ -457,6 +457,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, const char *language, int fla
   char *sp[5];
   struct parsedata pd;
   Repodata *data = 0;
+  Id blanr = -1;
 
   if ((flags & SUSETAGS_EXTEND) && repo->nrepodata)
     indesc = 1;
@@ -477,6 +478,8 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, const char *language, int fla
   linep = line;
   s = 0;
 
+  /* XXX deactivate test code */
+  blanr = 0;
   /*
    * read complete file
    * 
@@ -800,6 +803,12 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, const char *language, int fla
            continue;
           case CTAG('=', 'I', 'n', 's'):
            repodata_set_str(data, last_found_pack, langtag(&pd, SOLVABLE_MESSAGEINS, language), line + 6);
+           if (blanr)
+             {
+               /* XXX testcode */
+               repo_set_str(repo, blanr, SOLVABLE_MESSAGEINS, line + 6);
+               blanr--;
+             }
            continue;
           case CTAG('=', 'D', 'e', 'l'):
            repodata_set_str(data, last_found_pack, langtag(&pd, SOLVABLE_MESSAGEDEL, language), line + 6);
@@ -850,6 +859,9 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, const char *language, int fla
          case CTAG('=', 'C', 'k', 's'):
            set_checksum(data, last_found_pack, SOLVABLE_CHECKSUM, line + 6);
            break;
+         case CTAG('=', 'L', 'a', 'n'):
+           language = strdup(line + 6);
+           break;
 
          case CTAG('=', 'P', 'a', 't'):
          case CTAG('=', 'P', 'k', 'g'):
index 42e2352fc99f0a0006552fcd1a26f9275deccb1a..81e2e3a76cd118056a0a45d9fd8fefd802a38927 100644 (file)
@@ -381,6 +381,7 @@ struct cbdata {
   Id schematacache[256];
 
   Id *solvschemata;
+  Id *extraschemata;
 
   struct extdata *extdata;
 
@@ -624,16 +625,11 @@ setdirused(struct cbdata *cbdata, Dirpool *dp, Id dir)
 }
 
 static int
-repo_write_cb_needed(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
+repo_write_collect_needed(struct cbdata *cbdata, Repo *repo, Repodata *data, Repokey *key, KeyValue *kv)
 {
-  struct cbdata *cbdata = vcbdata;
-  Repo *repo = s ? s->repo : 0;
   Id id;
   int rm;
 
-#if 0
-  fprintf(stderr, "solvable %d (%s): key (%d)%s %d\n", s ? s - s->repo->pool->solvables : 0, s ? id2str(s->repo->pool, s->name) : "", key->name, id2str(repo->pool, key->name), key->type);
-#endif
   rm = cbdata->keymap[cbdata->keymapstart[data - data->repo->repodata] + (key - data->keys)];
   if (!rm)
     return SEARCH_NEXT_KEY;    /* we do not want this one */
@@ -665,9 +661,19 @@ repo_write_cb_needed(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, K
 }
 
 static int
-repo_write_cb_adddata(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
+repo_write_cb_needed(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
 {
   struct cbdata *cbdata = vcbdata;
+  Repo *repo = s ? s->repo : 0;
+#if 0
+  fprintf(stderr, "solvable %d (%s): key (%d)%s %d\n", s ? s - s->repo->pool->solvables : 0, s ? id2str(s->repo->pool, s->name) : "", key->name, id2str(repo->pool, key->name), key->type);
+#endif
+  return repo_write_collect_needed(cbdata, repo, data, key, kv);
+}
+
+static int
+repo_write_adddata(struct cbdata *cbdata, Repodata *data, Repokey *key, KeyValue *kv)
+{
   int rm;
   Id id;
   unsigned int u32;
@@ -764,6 +770,13 @@ repo_write_cb_adddata(void *vcbdata, Solvable *s, Repodata *data, Repokey *key,
   return 0;
 }
 
+static int
+repo_write_cb_adddata(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
+{
+  struct cbdata *cbdata = vcbdata;
+  return repo_write_adddata(cbdata, data, key, kv);
+}
+
 static int
 traverse_dirs(Dirpool *dp, Id *dirmap, Id n, Id dir, Id *used)
 {
@@ -1137,6 +1150,7 @@ for (i = 1; i < cbdata.nmykeys; i++)
   cbdata.schema = sat_calloc(cbdata.nmykeys, sizeof(Id));
   cbdata.sp = cbdata.schema;
   cbdata.solvschemata = sat_calloc(repo->nsolvables, sizeof(Id));
+  cbdata.extraschemata = sat_calloc(repo->nextra, sizeof(Id));
 
   idarraydata = repo->idarraydata;
 
@@ -1235,6 +1249,17 @@ for (i = 1; i < cbdata.nmykeys; i++)
       cbdata.solvschemata[n] = addschema(&cbdata, cbdata.schema);
       n++;
     }
+  if (repo->nextra && anyrepodataused)
+    for (i = -1; i >= -repo->nextra; i--)
+      {
+       Dataiterator di;
+       dataiterator_init(&di, repo, i, 0, 0, SEARCH_EXTRA | SEARCH_NO_STORAGE_SOLVABLE);
+       cbdata.sp = cbdata.schema;
+       while (dataiterator_step(&di))
+         repo_write_collect_needed(&cbdata, repo, di.data, di.key, &di.kv);
+       *cbdata.sp = 0;
+       cbdata.extraschemata[-1 - i] = addschema(&cbdata, cbdata.schema);
+      }
 
   /* If we have fileinfos to write, setup schemas and increment needid[]
      of the right strings.  */
@@ -1478,13 +1503,29 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
       n++;
     }
 
+  if (repo->nextra && anyrepodataused)
+    for (i = -1; i >= -repo->nextra; i--)
+      {
+       Dataiterator di;
+       dataiterator_init(&di, repo, i, 0, 0, SEARCH_EXTRA | SEARCH_NO_STORAGE_SOLVABLE);
+       entrysize = xd->len;
+       data_addid(xd, cbdata.extraschemata[-1 - i]);
+       cbdata.vstart = -1;
+       while (dataiterator_step(&di))
+         repo_write_adddata(&cbdata, di.data, di.key, &di.kv);
+       entrysize = xd->len - entrysize;
+       if (entrysize > maxentrysize)
+         maxentrysize = entrysize;
+      }
+
 /********************************************************************/
 
   /* write header */
 
   /* write file header */
   write_u32(fp, 'S' << 24 | 'O' << 16 | 'L' << 8 | 'V');
-  write_u32(fp, SOLV_VERSION_6);
+  write_u32(fp, repo->nextra ? SOLV_VERSION_7 : SOLV_VERSION_6);
+
 
   /* write counts */
   write_u32(fp, nstrings);
@@ -1494,6 +1535,8 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
   write_u32(fp, cbdata.nmykeys);
   write_u32(fp, cbdata.nmyschemata);
   write_u32(fp, nsubfiles);    /* info blocks.  */
+  if (repo->nextra)
+    write_u32(fp, repo->nextra);
   solv_flags = 0;
   solv_flags |= SOLV_FLAG_PREFIX_POOL;
   write_u32(fp, solv_flags);
@@ -1644,7 +1687,7 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
   /*
    * write Solvable data
    */
-  if (repo->nsolvables)
+  if (repo->nsolvables || repo->nextra)
     {
       write_id(fp, maxentrysize);
       write_id(fp, cbdata.extdata[0].len);
@@ -1685,7 +1728,7 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
            }
        }
       if (lpage)
-         write_compressed_page(fp, vpage, lpage);
+       write_compressed_page(fp, vpage, lpage);
     }
 
 #if 0
@@ -1721,6 +1764,7 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
       sat_free(cbdata.owndirpool->dirtraverse);
     }
   sat_free(needid);
+  sat_free(cbdata.extraschemata);
   sat_free(cbdata.solvschemata);
   sat_free(cbdata.myschemadata);
   sat_free(cbdata.myschemata);