- add repo_lookup_idarray(), repo_lookup_checksum(), repodata_set_idarray(), repodata...
authorMichael Schroeder <mls@suse.de>
Wed, 23 Mar 2011 14:57:53 +0000 (15:57 +0100)
committerMichael Schroeder <mls@suse.de>
Wed, 23 Mar 2011 14:57:53 +0000 (15:57 +0100)
src/repo.c
src/repo.h
src/repodata.c
src/repodata.h
src/solvable.c

index 265f880..2e14e03 100644 (file)
@@ -25,9 +25,7 @@
 #include "pool.h"
 #include "poolid_private.h"
 #include "util.h"
-#if 0
-#include "attr_store_p.h"
-#endif
+#include "chksum.h"
 
 #define IDARRAY_BLOCK     4095
 
@@ -867,16 +865,19 @@ repo_lookup_str(Repo *repo, Id entry, Id keyname)
   int i;
   const char *str;
 
-  switch(keyname)
+  if (entry >= 0)
     {
-    case SOLVABLE_NAME:
-      return id2str(pool, pool->solvables[entry].name);
-    case SOLVABLE_ARCH:
-      return id2str(pool, pool->solvables[entry].arch);
-    case SOLVABLE_EVR:
-      return id2str(pool, pool->solvables[entry].evr);
-    case SOLVABLE_VENDOR:
-      return id2str(pool, pool->solvables[entry].vendor);
+      switch (keyname)
+       {
+       case SOLVABLE_NAME:
+         return id2str(pool, pool->solvables[entry].name);
+       case SOLVABLE_ARCH:
+         return id2str(pool, pool->solvables[entry].arch);
+       case SOLVABLE_EVR:
+         return id2str(pool, pool->solvables[entry].evr);
+       case SOLVABLE_VENDOR:
+         return id2str(pool, pool->solvables[entry].vendor);
+       }
     }
   for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
     {
@@ -901,11 +902,14 @@ repo_lookup_num(Repo *repo, Id entry, Id keyname, unsigned int notfound)
   int i;
   unsigned int value;
 
-  if (keyname == RPM_RPMDBID)
+  if (entry >= 0)
     {
-      if (repo->rpmdbid && entry >= repo->start && entry < repo->end)
-       return repo->rpmdbid[entry - repo->start];
-      return notfound;
+      if (keyname == RPM_RPMDBID)
+       {
+         if (repo->rpmdbid && entry >= repo->start && entry < repo->end)
+           return repo->rpmdbid[entry - repo->start];
+         return notfound;
+       }
     }
   for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
     {
@@ -928,17 +932,20 @@ repo_lookup_id(Repo *repo, Id entry, Id keyname)
   int i;
   Id id;
 
-  switch(keyname)
-    {   
-    case SOLVABLE_NAME:
-      return repo->pool->solvables[entry].name;
-    case SOLVABLE_ARCH:
-      return repo->pool->solvables[entry].arch;
-    case SOLVABLE_EVR:
-      return repo->pool->solvables[entry].evr;
-    case SOLVABLE_VENDOR:
-      return repo->pool->solvables[entry].vendor;
-    }   
+  if (entry >= 0)
+    {
+      switch (keyname)
+       {   
+       case SOLVABLE_NAME:
+         return repo->pool->solvables[entry].name;
+       case SOLVABLE_ARCH:
+         return repo->pool->solvables[entry].arch;
+       case SOLVABLE_EVR:
+         return repo->pool->solvables[entry].evr;
+       case SOLVABLE_VENDOR:
+         return repo->pool->solvables[entry].vendor;
+       }   
+    }
   for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
     {   
       if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
@@ -954,6 +961,67 @@ repo_lookup_id(Repo *repo, Id entry, Id keyname)
   return 0;
 }
 
+static int
+lookup_idarray_solvable(Repo *repo, Offset off, Queue *q)
+{
+  Id *p;
+
+  queue_empty(q);
+  if (off)
+    for (p = repo->idarraydata + off; *p; p++)
+      queue_push(q, *p);
+  return 1;
+}
+
+int
+repo_lookup_idarray(Repo *repo, Id entry, Id keyname, Queue *q)
+{
+  Repodata *data;
+  int i;
+  if (entry >= 0)
+    {
+      switch (keyname)
+        {
+       case SOLVABLE_PROVIDES:
+         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].provides, q);
+       case SOLVABLE_OBSOLETES:
+         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].obsoletes, q);
+       case SOLVABLE_CONFLICTS:
+         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].conflicts, q);
+       case SOLVABLE_REQUIRES:
+         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].requires, q);
+       case SOLVABLE_RECOMMENDS:
+         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].recommends, q);
+       case SOLVABLE_SUGGESTS:
+         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].suggests, q);
+       case SOLVABLE_SUPPLEMENTS:
+         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].supplements, q);
+       case SOLVABLE_ENHANCES:
+         return lookup_idarray_solvable(repo, repo->pool->solvables[entry].enhances, q);
+        }
+    }
+  for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
+    {   
+      if (entry != SOLVID_META && (entry < data->start || entry >= data->end))
+       continue;
+      if (!repodata_precheck_keyname(data, keyname))
+       continue;
+      if (repodata_lookup_idarray(data, entry, keyname, q))
+       {
+         if (data->localpool)
+           {
+             for (i = 0; i < q->count; i++)
+               q->elements[i] = repodata_globalize_id(data, q->elements[i], 1);
+           }
+         return 1;
+       }
+      if (repodata_lookup_type(data, entry, keyname))
+       break;
+    }
+  queue_empty(q);
+  return 0;
+}
+
 const unsigned char *
 repo_lookup_bin_checksum(Repo *repo, Id entry, Id keyname, Id *typep)
 {
@@ -977,6 +1045,13 @@ repo_lookup_bin_checksum(Repo *repo, Id entry, Id keyname, Id *typep)
   return 0;
 }
 
+const char *
+repo_lookup_checksum(Repo *repo, Id entry, Id keyname, Id *typep)
+{
+  const unsigned char *chk = repo_lookup_bin_checksum(repo, entry, keyname, typep);
+  return chk ? pool_bin2hex(repo->pool, chk, sat_chksum_len(*typep)) : 0;
+}
+
 int
 repo_lookup_void(Repo *repo, Id entry, Id keyname)
 {
@@ -1060,13 +1135,26 @@ void
 repo_set_id(Repo *repo, Id p, Id keyname, Id id)
 {
   Repodata *data = repo_last_repodata(repo);
+  if (data->localpool)
+    id = repodata_localize_id(data, id, 1);
   repodata_set_id(data, p, keyname, id);
 }
 
 void
 repo_set_num(Repo *repo, Id p, Id keyname, unsigned int num)
 {
-  Repodata *data = repo_last_repodata(repo);
+  Repodata *data;
+  if (p >= 0)
+    {
+      if (keyname == RPM_RPMDBID)
+       {
+         if (!repo->rpmdbid)
+           repo->rpmdbid = repo_sidedata_create(repo, sizeof(Id));
+         repo->rpmdbid[p] = num;
+         return;
+       }
+    }
+  data = repo_last_repodata(repo);
   repodata_set_num(data, p, keyname, num);
 }
 
index e73ad35..aade9e3 100644 (file)
@@ -196,13 +196,15 @@ Repodata *repo_last_repodata(Repo *repo);
 void repo_search(Repo *repo, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata);
 
 /* returns the string value of the attribute, or NULL if not found */
-Id repo_lookup_type(Repo *repo, Id entry, Id key);
-const char *repo_lookup_str(Repo *repo, Id entry, Id key);
+Id repo_lookup_type(Repo *repo, Id entry, Id keyname);
+const char *repo_lookup_str(Repo *repo, Id entry, Id keyname);
 /* returns the integer value of the attribute, or notfound if not found */
-unsigned int repo_lookup_num(Repo *repo, Id entry, Id key, unsigned int notfound);
-Id repo_lookup_id(Repo *repo, Id entry, Id keyid);
-int repo_lookup_void(Repo *repo, Id entry, Id keyid);
-const unsigned char *repo_lookup_bin_checksum(Repo *repo, Id entry, Id keyid, Id *typep);
+unsigned int repo_lookup_num(Repo *repo, Id entry, Id keyname, unsigned int notfound);
+Id repo_lookup_id(Repo *repo, Id entry, Id keyname);
+int repo_lookup_idarray(Repo *repo, Id entry, Id keyname, Queue *q);
+int repo_lookup_void(Repo *repo, Id entry, Id keyname);
+const char *repo_lookup_checksum(Repo *repo, Id entry, Id keyname, Id *typep);
+const unsigned char *repo_lookup_bin_checksum(Repo *repo, Id entry, Id keyname, Id *typep);
 
 typedef struct _Datamatcher {
   int flags;
index bde6579..8970d3d 100644 (file)
@@ -705,6 +705,14 @@ repodata_globalize_id(Repodata *data, Id id, int create)
   return 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, id2str(data->repo->pool, id), create);
+}
+
 
 /************************************************************************
  * data search
@@ -1828,7 +1836,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 +1846,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)
@@ -2208,6 +2215,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);
@@ -2395,14 +2419,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 +2494,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 +2509,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 +2520,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 +2546,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;
       }
index 589edd7..b0d9ea8 100644 (file)
@@ -230,6 +230,8 @@ void repodata_set_bin_checksum(Repodata *data, Id solvid, Id keyname, Id type,
                               const unsigned char *buf);
 void repodata_set_checksum(Repodata *data, Id solvid, Id keyname, Id type,
                           const char *str);
+void repodata_set_idarray(Repodata *data, Id solvid, Id keyname, Queue *q);
+
 
 /* directory (for package file list) */
 void repodata_add_dirnumnum(Repodata *data, Id solvid, Id keyname, Id dir, Id num, Id num2);
@@ -262,6 +264,7 @@ void repodata_disable_paging(Repodata *data);
 
 /* helper functions */
 Id repodata_globalize_id(Repodata *data, Id id, int create);
+Id repodata_localize_id(Repodata *data, Id id, int create);
 Id repodata_str2dir(Repodata *data, const char *dir, int create);
 const char *repodata_dir2str(Repodata *data, Id did, const char *suf);
 const char *repodata_chk2str(Repodata *data, Id type, const unsigned char *buf);
index 6a2889c..1331331 100644 (file)
@@ -46,24 +46,12 @@ solvable_lookup_id(Solvable *s, Id keyname)
 int
 solvable_lookup_idarray(Solvable *s, Id keyname, Queue *q)
 {
-  Dataiterator di;
-  int found = 0;
-
-  queue_empty(q);
   if (!s->repo)
-    return 0;
-  dataiterator_init(&di, s->repo->pool, s->repo, s - s->repo->pool->solvables, keyname, 0, SEARCH_ARRAYSENTINEL);
-  while (dataiterator_step(&di))
     {
-      if (di.key->type != REPOKEY_TYPE_IDARRAY && di.key->type != REPOKEY_TYPE_REL_IDARRAY)
-       continue;
-      found = 1;
-      if (di.kv.eof)
-       break;
-      queue_push(q, di.kv.id);
+      queue_empty(q);
+      return 0;
     }
-  dataiterator_free(&di);
-  return found;
+  return repo_lookup_idarray(s->repo, s - s->repo->pool->solvables, keyname, q);
 }
 
 const char *
@@ -243,11 +231,13 @@ solvable_get_location(Solvable *s, unsigned int *medianrp)
   char *loc;
   const char *mediadir, *mediafile;
 
-  *medianrp = 0;
+  if (medianrp)
+    *medianrp = 0;
   if (!s->repo)
     return 0;
   pool = s->repo->pool;
-  *medianrp = solvable_lookup_num(s, SOLVABLE_MEDIANR, 1);
+  if (medianrp)
+    *medianrp = solvable_lookup_num(s, SOLVABLE_MEDIANR, 1);
   if (solvable_lookup_void(s, SOLVABLE_MEDIADIR))
     mediadir = id2str(pool, s->arch);
   else
@@ -503,8 +493,8 @@ pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *con
 }
 
 /* Tests if two solvables have identical content. Currently
- * both solvables need to come from the same pool */
-
+ * both solvables need to come from the same pool
+ */
 int
 solvable_identical(Solvable *s1, Solvable *s2)
 {