#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
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++)
{
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++)
{
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))
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)
{
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)
{
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);
}
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;
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
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;
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)
}
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);
/*********************************/
+/* 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;
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);
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;
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;
}
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;
}
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);
/* 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);
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 *
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
}
/* 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)
{