#include "repopack.h"
#include "repopage.h"
-extern unsigned int compress_buf (const unsigned char *in, unsigned int in_len,
- unsigned char *out, unsigned int out_len);
-extern unsigned int unchecked_decompress_buf (const unsigned char *in,
- unsigned int in_len,
- unsigned char *out,
- unsigned int out_len);
-
#define REPODATA_BLOCK 255
+static unsigned char *data_skip_key(Repodata *data, unsigned char *dp, Repokey *key);
void
repodata_initdata(Repodata *data, Repo *repo, int localpool)
data->localpool = localpool;
if (localpool)
stringpool_init_empty(&data->spool);
+ /* dirpool_init(&data->dirpool); just zeros out again */
data->keys = sat_calloc(1, sizeof(Repokey));
data->nkeys = 1;
data->schemata = sat_calloc(1, sizeof(Id));
Id *sp, cid;
Id *schematahash;
+ if (!*schema)
+ return 0; /* XXX: allow empty schema? */
if ((schematahash = data->schematahash) == 0)
{
data->schematahash = schematahash = sat_calloc(256, sizeof(Id));
- for (i = 0; i < data->nschemata; i++)
+ for (i = 1; i < data->nschemata; i++)
{
for (sp = data->schemadata + data->schemata[i], h = 0; *sp; len++)
h = h * 7 + *sp++;
h &= 255;
- schematahash[h] = i + 1;
+ schematahash[h] = i;
}
data->schemadata = sat_extend_resize(data->schemadata, data->schemadatalen, sizeof(Id), SCHEMATADATA_BLOCK);
data->schemata = sat_extend_resize(data->schemata, data->nschemata, sizeof(Id), SCHEMATA_BLOCK);
cid = schematahash[h];
if (cid)
{
- cid--;
if (!memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id)))
return cid;
- /* cache conflict */
- for (cid = 0; cid < data->nschemata; cid++)
+ /* cache conflict, do a slow search */
+ for (cid = 1; cid < data->nschemata; cid++)
if (!memcmp(data->schemadata + data->schemata[cid], schema, len * sizeof(Id)))
return cid;
}
memcpy(data->schemadata + data->schemadatalen, schema, len * sizeof(Id));
data->schemata[data->nschemata] = data->schemadatalen;
data->schemadatalen += len;
- schematahash[h] = data->nschemata + 1;
+ schematahash[h] = data->nschemata;
#if 0
fprintf(stderr, "schema2id: new schema\n");
#endif
if (data->localpool)
id = stringpool_strn2id(&data->spool, dir, dire - dir, create);
else
- id = strn2id(data->repo->pool, dir, dire - dir, create);
+ id = pool_strn2id(data->repo->pool, dir, dire - dir, create);
if (!id)
return 0;
parent = dirpool_add_dir(&data->dirpool, parent, id, create);
return dp;
}
-unsigned char *
+static unsigned char *
data_skip_key(Repodata *data, unsigned char *dp, Repokey *key)
{
int nentries, schema;
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 = repopagestore_load_page_range(&data->store, off / BLOB_PAGESIZE, (off + len - 1) / BLOB_PAGESIZE);
+ /* fprintf(stderr, "key %d page %d\n", key->name, off / REPOPAGE_BLOBSIZE); */
+ dp = repopagestore_load_page_range(&data->store, off / REPOPAGE_BLOBSIZE, (off + len - 1) / REPOPAGE_BLOBSIZE);
if (dp)
- dp += off % BLOB_PAGESIZE;
+ dp += off % REPOPAGE_BLOBSIZE;
return dp;
}
if (key->type == REPOKEY_TYPE_STR)
return (const char *)dp;
if (key->type == REPOKEY_TYPE_CONSTANTID)
- return id2str(data->repo->pool, key->size);
- if (key->type == REPOKEY_TYPE_ID)
+ id = key->size;
+ else if (key->type == REPOKEY_TYPE_ID)
dp = data_read_id(dp, &id);
else
return 0;
if (data->localpool)
- return data->spool.stringspace + data->spool.strings[id];
- return id2str(data->repo->pool, id);
+ return stringpool_id2str(&data->spool, id);
+ return pool_id2str(data->repo->pool, id);
}
int
|| key->type == REPOKEY_TYPE_U32
|| key->type == REPOKEY_TYPE_CONSTANT)
{
+ kv.num = 0;
dp = data_fetch(dp, &kv, key);
*value = kv.num;
return 1;
{
if (!id || !data || !data->localpool)
return id;
- return str2id(data->repo->pool, stringpool_id2str(&data->spool, id), create);
+ return pool_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, pool_id2str(data->repo->pool, id), create);
}
if (data && data->localpool)
kv->str = stringpool_id2str(&data->spool, kv->id);
else
- kv->str = id2str(pool, kv->id);
+ kv->str = pool_id2str(pool, kv->id);
if ((flags & SEARCH_SKIP_KIND) != 0 && key->storage == KEY_STORAGE_SOLVABLE)
{
const char *s;
dataiterator_set_search(Dataiterator *di, Repo *repo, Id p)
{
di->repo = repo;
- di->repoid = -1;
+ di->repoid = 0;
di->flags &= ~SEARCH_THISSOLVID;
di->nparents = 0;
di->rootlevel = 0;
}
if (!repo)
{
- di->repoid = 0;
+ di->repoid = 1;
di->repo = di->pool->repos[0];
}
di->state = di_enterrepo;
/* FALLTHROUGH */
case di_nextrepo: di_nextrepo:
- if (di->repoid >= 0)
+ if (di->repoid > 0)
{
di->repoid++;
di->repodataid = 0;
- if (di->repoid < di->pool->nrepos)
+ if (di->repoid - 1 < di->pool->nrepos)
{
- di->repo = di->pool->repos[di->repoid];
+ di->repo = di->pool->repos[di->repoid - 1];
goto di_enterrepo;
}
}
di->state = di_bye;
return;
}
- di->repoid = -1;
+ di->repoid = 0;
di->data = di->repo->repodata + di->pool->pos.repodataid;
di->repodataid = -1;
di->solvid = solvid;
if (solvid > 0)
{
di->repo = di->pool->solvables[solvid].repo;
- di->repoid = -1;
+ di->repoid = 0;
}
- else if (di->repoid >= 0)
+ else if (di->repoid > 0)
{
if (!di->pool->nrepos)
{
di->state = di_bye;
return;
}
+ di->repoid = 1;
di->repo = di->pool->repos[0];
- di->repoid = 0;
}
di->repodataid = 0;
di->solvid = solvid;
di->kv.parent = 0;
di->rootlevel = 0;
di->repo = repo;
- di->repoid = -1;
+ di->repoid = 0; /* 0 means stay at repo */
di->repodataid = 0;
di->solvid = 0;
di->flags &= ~SEARCH_THISSOLVID;
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)
if (data->localpool)
id = stringpool_str2id(&data->spool, str, 1);
else
- id = str2id(data->repo->pool, str, 1);
+ id = pool_str2id(data->repo->pool, str, 1);
key.name = keyname;
key.type = REPOKEY_TYPE_ID;
key.size = 0;
data->attrdatalen += l;
}
-static int
-hexstr2bytes(unsigned char *buf, const char *str, int buflen)
-{
- int i;
- for (i = 0; i < buflen; i++)
- {
-#define c2h(c) (((c)>='0' && (c)<='9') ? ((c)-'0') \
- : ((c)>='a' && (c)<='f') ? ((c)-('a'-10)) \
- : ((c)>='A' && (c)<='F') ? ((c)-('A'-10)) \
- : -1)
- int v = c2h(*str);
- str++;
- if (v < 0)
- return 0;
- buf[i] = v;
- v = c2h(*str);
- str++;
- if (v < 0)
- return 0;
- buf[i] = (buf[i] << 4) | v;
-#undef c2h
- }
- return buflen;
-}
-
void
repodata_set_checksum(Repodata *data, Id solvid, Id keyname, Id type,
const char *str)
if (!(l = sat_chksum_len(type)))
return;
- if (hexstr2bytes(buf, str, l) != l)
+ if (l > sizeof(buf) || sat_hex2bin(&str, buf, l) != l)
return;
repodata_set_bin_checksum(data, solvid, keyname, type, buf);
}
const char *
repodata_chk2str(Repodata *data, Id type, const unsigned char *buf)
{
- int i, l;
- char *str, *s;
+ int l;
if (!(l = sat_chksum_len(type)))
return "";
- s = str = pool_alloctmpspace(data->repo->pool, 2 * l + 1);
- for (i = 0; i < l; i++)
- {
- unsigned char v = buf[i];
- unsigned char w = v >> 4;
- *s++ = w >= 10 ? w + ('a' - 10) : w + '0';
- w = v & 15;
- *s++ = w >= 10 ? w + ('a' - 10) : w + '0';
- }
- *s = 0;
- return str;
+ return pool_bin2hex(data->repo->pool, buf, l);
}
/* rpm filenames don't contain the epoch, so strip it */
static inline const char *
evrid2vrstr(Pool *pool, Id evrid)
{
- const char *p, *evr = id2str(pool, evrid);
+ const char *p, *evr = pool_id2str(pool, evrid);
if (!evr)
return evr;
for (p = evr; *p >= '0' && *p <= '9'; p++)
s = pool->solvables + solvid;
if (dir && l)
{
- str = id2str(pool, s->arch);
+ str = pool_id2str(pool, s->arch);
if (!strncmp(dir, str, l) && !str[l])
repodata_set_void(data, solvid, SOLVABLE_MEDIADIR);
else if (!dir[l])
}
}
fp = file;
- str = id2str(pool, s->name);
+ str = pool_id2str(pool, s->name);
l = strlen(str);
if ((!l || !strncmp(fp, str, l)) && fp[l] == '-')
{
if ((!l || !strncmp(fp, str, l)) && fp[l] == '.')
{
fp += l + 1;
- str = id2str(pool, s->arch);
+ str = pool_id2str(pool, s->arch);
l = strlen(str);
if ((!l || !strncmp(fp, str, l)) && !strcmp(fp + l, ".rpm"))
{
}
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);
if (data->localpool)
id = stringpool_str2id(&data->spool, str, 1);
else
- id = str2id(data->repo->pool, str, 1);
+ id = pool_str2id(data->repo->pool, str, 1);
repodata_add_idarray(data, solvid, keyname, id);
}
/*********************************/
+/* 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;
}
}
key = data->keys + *keyp;
#if 0
- fprintf(stderr, "internalize %d(%d):%s:%s\n", entry, entry + data->start, id2str(data->repo->pool, key->name), id2str(data->repo->pool, key->type));
+ fprintf(stderr, "internalize %d(%d):%s:%s\n", entry, entry + data->start, pool_id2str(data->repo->pool, key->name), pool_id2str(data->repo->pool, key->type));
#endif
ndp = dp;
if (oldcount)
{
Repo *repo = data->repo;
Pool *pool = repo->pool;
- int r;
+ int r, i;
+ struct _Pool_tmpspace oldtmpspace;
if (!pool->loadcallback)
{
return;
}
data->state = REPODATA_LOADING;
+
+ /* save tmp space */
+ oldtmpspace = pool->tmpspace;
+ memset(&pool->tmpspace, 0, sizeof(pool->tmpspace));
+
r = pool->loadcallback(pool, data, pool->loadcallbackdata);
+
+ /* restore tmp space */
+ for (i = 0; i < POOL_TMPSPACEBUF; i++)
+ sat_free(pool->tmpspace.buf[i]);
+ pool->tmpspace = oldtmpspace;
+
data->state = r ? REPODATA_AVAILABLE : REPODATA_ERROR;
}