Pull together attribute store and repo. dumpsolv actually now really
authorMichael Matz <matz@suse.de>
Sat, 8 Dec 2007 01:24:52 +0000 (01:24 +0000)
committerMichael Matz <matz@suse.de>
Sat, 8 Dec 2007 01:24:52 +0000 (01:24 +0000)
can also show the content of test.attr, yeah.

src/attr_store.c
src/attr_store_p.h
src/repo.c
src/repo.h
src/repo_solv.c
tools/dumpsolv.c

index bd4c8eb..de16bb4 100644 (file)
@@ -125,8 +125,7 @@ add_attr (Attrstore *s, unsigned int entry, LongNV attr)
 {
   LongNV *nv;
   unsigned int len;
-  if (entry >= s->entries)
-    return;
+  ensure_entry (s, entry);
   if (attr.key >= s->nkeys)
     return;
   nv = s->attrs[entry];
@@ -262,9 +261,9 @@ static Id read_id (FILE *fp, Id max);
 /* This routine is used only when attributes are embedded into the
    normal repo SOLV file.  */
 void
-add_attr_from_file (Attrstore *s, unsigned entry, Id name, int type, FILE *fp)
+add_attr_from_file (Attrstore *s, unsigned entry, Id name, int type, Id *idmap, unsigned maxid, FILE *fp)
 {
-  //Pool *pool = s->pool;
+  Pool *pool = s->pool;
   //fprintf (stderr, "%s: attribute in a repo SOLV?\n", id2str (pool, name));
   switch (type)
     {
@@ -325,8 +324,13 @@ add_attr_from_file (Attrstore *s, unsigned entry, Id name, int type, FILE *fp)
       case TYPE_ATTR_LOCALIDS:
         {
          Id i;
-         while ((i = read_id(fp, 0)) != 0)
-           add_attr_localids_id (s, entry, name, i);
+         /* The read ID will be pool-based.  */
+         while ((i = read_id(fp, maxid)) != 0)
+           {
+             if (idmap)
+               i = idmap[i];
+             add_attr_localids_id (s, entry, name, str2localid (s, id2str (pool, i), 1));
+           }
        }
        break;
       default:
@@ -1005,7 +1009,7 @@ write_attr_store (FILE *fp, Attrstore *s)
         s->ent2attr[i] += start, start = s->ent2attr[i];
     }
 
-  if (fwrite (s->flat_attrs, s->attr_next_free, 1, fp) != 1)
+  if (fwrite (s->flat_attrs + 1, s->attr_next_free - 1, 1, fp) != 1)
     {
       perror ("write error");
       exit (1);
@@ -1360,7 +1364,8 @@ attr_store_read (FILE *fp, Pool *pool)
 
   s->attr_next_free = start;
   s->flat_attrs = xmalloc (((s->attr_next_free + FLAT_ATTR_BLOCK) & ~FLAT_ATTR_BLOCK) * sizeof (s->flat_attrs[0]));
-  if (fread (s->flat_attrs, s->attr_next_free, 1, fp) != 1)
+  s->flat_attrs[0] = 0;
+  if (fread (s->flat_attrs + 1, s->attr_next_free - 1, 1, fp) != 1)
     {
       perror ("read error");
       exit (1);
index d23d2c8..bc9be3a 100644 (file)
@@ -75,7 +75,7 @@ struct _Attrstore
   unsigned int packed:1;
 };
 
-void add_attr_from_file (Attrstore *s, unsigned entry, Id name, int type, FILE *fp);
+void add_attr_from_file (Attrstore *s, unsigned entry, Id name, int type, Id *idmap, unsigned maxid, FILE *fp);
 
 #define get_num(ptr,val) do { \
   typedef int __wrong_buf__[(1-sizeof((ptr)[0])) * (sizeof((ptr)[0])-1)];\
index 05fed66..f8f2d34 100644 (file)
@@ -20,6 +20,7 @@
 #include "pool.h"
 #include "poolid_private.h"
 #include "util.h"
+#include "attr_store_p.h"
 
 #define IDARRAY_BLOCK     4095
 
@@ -543,4 +544,36 @@ repo_lookup_id(Solvable *s, Id key)
 }
 #endif
 
+static int
+key_cmp (const void *pa, const void *pb)
+{
+  struct key { Id name; unsigned type; };
+  struct key *a = (struct key*)pa;
+  struct key *b = (struct key*)pb;
+  return a->name - b->name;
+}
+
+void
+repo_add_attrstore (Repo *repo, Attrstore *s)
+{
+  unsigned i;
+  Repodata *data;
+  repo->nrepodata++;
+  repo->repodata = xrealloc (repo->repodata, repo->nrepodata * sizeof (*data));
+  data = repo->repodata + repo->nrepodata - 1;
+  memset (data, 0, sizeof (*data));
+  data->s = s;
+  data->nkeys = s->nkeys;
+  if (s->nkeys)
+    {
+      data->keys = xmalloc (data->nkeys * sizeof (data->keys[0]));
+      for (i = 0; i < data->nkeys; i++)
+        {
+          data->keys[i].name = s->keys[i].name;
+         data->keys[i].type = s->keys[i].type;
+       }
+      qsort (data->keys, data->nkeys, sizeof (data->keys[0]), key_cmp);
+    }
+}
+
 // EOF
index 44b7f3a..39e3c49 100644 (file)
 
 #include "pooltypes.h"
 #include "pool.h"
+#include "attr_store.h"
+
+typedef struct _Repodata {
+  /* Keys provided by this attribute store, sorted by name value.
+     The same keys may be provided by multiple attribute stores, but
+     then only for different solvables.  I.e. the relation
+       (solvable,name) -> store
+     has to be injective.  */
+  struct {
+    Id name;
+    unsigned type;
+  } *keys;
+  /* Length of names.  */
+  unsigned nkeys;
+  /* The attribute store itself.  */
+  Attrstore *s;
+  /* A filename where to find this attribute store, or where to store
+     it.  May be NULL, in which case we can't load it on demand or store
+     into it.  */
+  const char *name;
+  /* The SHA1 checksum of the file.  */
+  unsigned char checksum[20];
+} Repodata;
 
 typedef struct _Repo {
   const char *name;
@@ -30,6 +53,11 @@ typedef struct _Repo {
   Offset lastoff;
 
   Id *rpmdbid;
+
+  /* The attribute stores we know about.  */
+  Repodata *repodata;
+  /* Number of attribute stores..  */
+  unsigned nrepodata;
 } Repo;
 
 extern Repo *repo_create(Pool *pool, const char *name);
@@ -41,6 +69,8 @@ extern Offset repo_addid_dep(Repo *repo, Offset olddeps, Id id, int isreq);
 extern Offset repo_reserve_ids(Repo *repo, Offset olddeps, int num);
 extern Offset repo_fix_legacy(Repo *repo, Offset provides, Offset supplements);
 
+extern void repo_add_attrstore (Repo *repo, Attrstore *s);
+
 static inline const char *repo_name(const Repo *repo)
 {
   return repo->name;
index a7dcd57..61bb9d1 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "repo_solv.h"
 #include "util.h"
+#include "attr_store_p.h"
 
 #define INTERESTED_START       SOLVABLE_NAME
 #define INTERESTED_END         SOLVABLE_FRESHENS
@@ -191,7 +192,6 @@ struct key {
   Id size;
 };
 
-
 // ----------------------------------------------
 
 /*
@@ -206,6 +206,7 @@ repo_add_solv(Repo *repo, FILE *fp)
   int i, l;
   unsigned int numid, numrel, numsolv;
   unsigned int numkeys, numschemata, numinfo;
+  Attrstore *embedded_store = 0;
 
   int type;
   Offset sizeid;
@@ -520,9 +521,16 @@ repo_add_solv(Repo *repo, FILE *fp)
              case TYPE_ID:
                read_id(fp, numid + numrel);   /* just check Id */
                break;
+             case TYPE_ATTR_CHUNK:
+               read_id(fp, 0);
+               /* Fallthrough.  */
+             case TYPE_ATTR_INT:
+               read_id(fp, 0);
+               break;
              case TYPE_U32:
                read_u32(fp);
                break;
+             case TYPE_ATTR_STRING:
              case TYPE_STR:
                while(read_u8(fp) != 0)
                  ;
@@ -532,6 +540,11 @@ repo_add_solv(Repo *repo, FILE *fp)
                while ((read_u8(fp) & 0xc0) != 0)
                  ;
                break;
+             case TYPE_ATTR_INTLIST:
+             case TYPE_ATTR_LOCALIDS:
+               while (read_id(fp, 0) != 0)
+                 ;
+               break;
              default:
                pool_debug(pool, SAT_FATAL, "unknown type %d\n", type);
                exit(0);
@@ -540,10 +553,12 @@ repo_add_solv(Repo *repo, FILE *fp)
     }
 
   /*******  Part 6: packed sizes (optional)  ****************************/
+  char *exists = 0;
   if ((solvflags & SOLV_FLAG_PACKEDSIZES) != 0)
     {
+      exists = xmalloc (numsolv);
       for (i = 0; i < numsolv; i++)
-       read_id(fp, 0);
+       exists[i] = read_id(fp, 0) != 0;
     }
 
   /*******  Part 7: item data *******************************************/
@@ -660,6 +675,15 @@ repo_add_solv(Repo *repo, FILE *fp)
                  else if (id == SOLVABLE_FRESHENS)
                    s->freshens = ido;
                  break;
+               case TYPE_ATTR_INT:
+               case TYPE_ATTR_CHUNK:
+               case TYPE_ATTR_STRING:
+               case TYPE_ATTR_INTLIST:
+               case TYPE_ATTR_LOCALIDS:
+                 if (!embedded_store)
+                   embedded_store = new_store (pool);
+                 add_attr_from_file (embedded_store, i, id, type, idmap, numid, fp);
+                 break;
                }
            }
        }
@@ -674,6 +698,8 @@ repo_add_solv(Repo *repo, FILE *fp)
     }
   for (i = 0; i < numsolv; i++, s++)
     {
+      if (exists && !exists[i])
+        continue;
       Id *keyp = schemadata + schemata[read_id(fp, numschemata)];
       while ((key = *keyp++) != 0)
        {
@@ -745,9 +771,24 @@ repo_add_solv(Repo *repo, FILE *fp)
                POOL_DEBUG(SAT_DEBUG_STATS,"  %s\n", dep2str(pool, repo->idarraydata[ido]));
 #endif
              break;
+           case TYPE_ATTR_INT:
+           case TYPE_ATTR_CHUNK:
+           case TYPE_ATTR_STRING:
+           case TYPE_ATTR_INTLIST:
+           case TYPE_ATTR_LOCALIDS:
+             if (!embedded_store)
+               embedded_store = new_store (pool);
+             add_attr_from_file (embedded_store, i, id, keys[key].type, idmap, numid, fp);
+             break;
            }
        }
     }
+  xfree(exists);
+  if (embedded_store)
+    {
+      attr_store_pack (embedded_store);
+      repo_add_attrstore (repo, embedded_store);
+    }
   xfree(idmap);
   xfree(schemata);
   xfree(schemadata);
index 19231ce..8cbbc2f 100644 (file)
 
 #include "pool.h"
 #include "repo_solv.h"
+#include "attr_store.h"
+#include "attr_store_p.h"
+
+static void
+dump_attrs_1 (Attrstore *s, unsigned int entry)
+{
+  attr_iterator ai;
+  FOR_ATTRS (s, entry, &ai)
+    {
+      fprintf (stdout, "%s:", id2str (s->pool, ai.name));
+      switch (ai.type)
+       {
+       case TYPE_ATTR_INT:
+         fprintf (stdout, "int  %u\n", ai.as_int);
+         break;
+       case TYPE_ATTR_CHUNK:
+         {
+           const char *str = attr_retrieve_blob (s, ai.as_chunk[0], ai.as_chunk[1]);
+           if (str)
+             fprintf (stdout, "blob %s\n", str);
+           else
+             fprintf (stdout, "blob %u+%u\n", ai.as_chunk[0], ai.as_chunk[1]);
+         }
+         break;
+       case TYPE_ATTR_STRING:
+         fprintf (stdout, "str  %s\n", ai.as_string);
+         break;
+       case TYPE_ATTR_INTLIST:
+         {
+           fprintf (stdout, "lint\n ");
+           while (1)
+             {
+               int val;
+               get_num (ai.as_numlist, val);
+               if (!val)
+                 break;
+               fprintf (stdout, " %d", val);
+             }
+           fprintf (stdout, "\n");
+           break;
+         }
+       case TYPE_ATTR_LOCALIDS:
+         {
+           fprintf (stdout, "lids");
+           while (1)
+             {
+               Id val;
+               get_num (ai.as_numlist, val);
+               if (!val)
+                 break;
+               fprintf (stdout, "\n  %s(%d)", localid2str (s, val), val);
+             }
+           fprintf (stdout, "\n");
+           break;
+         }
+       default:
+         break;
+       }
+    }
+}
+
+static void
+dump_attrs (Repo *repo, unsigned int entry)
+{
+  unsigned i;
+  for (i = 0; i < repo->nrepodata; i++)
+    {
+      Attrstore *s = repo->repodata[i].s;
+      if (s && entry < s->entries)
+        dump_attrs_1 (s, entry);
+    }
+}
 
 static void
 printids(Repo *repo, char *kind, Offset ido)
@@ -51,8 +123,9 @@ int main(int argc, char **argv)
       if (s->repo != repo)
        continue;
       printf("\n");
-      printf("solvable %d:\n", n++);
-      printf("name: %s %s %s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
+      printf("solvable %d:\n", n);
+      if (s->name || s->evr || s->arch)
+        printf("name: %s %s %s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
       if (s->vendor)
         printf("vendor: %s\n", id2str(pool, s->vendor));
       printids(repo, "provides", s->provides);
@@ -64,6 +137,8 @@ int main(int argc, char **argv)
       printids(repo, "supplements", s->supplements);
       printids(repo, "enhances", s->enhances);
       printids(repo, "freshens", s->freshens);
+      dump_attrs (repo, n - 1);
+      n++;
     }
   pool_free(pool);
   exit(0);