#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)
{
memset(data, 0, sizeof (*data));
+ data->repodataid = data - repo->repodata;
data->repo = repo;
data->localpool = localpool;
if (localpool)
stringpool_init_empty(&data->spool);
- data->keys = sat_calloc(1, sizeof(Repokey));
+ /* dirpool_init(&data->dirpool); just zeros out again */
+ data->keys = solv_calloc(1, sizeof(Repokey));
data->nkeys = 1;
- data->schemata = sat_calloc(1, sizeof(Id));
- data->schemadata = sat_calloc(1, sizeof(Id));
+ data->schemata = solv_calloc(1, sizeof(Id));
+ data->schemadata = solv_calloc(1, sizeof(Id));
data->nschemata = 1;
data->schemadatalen = 1;
repopagestore_init(&data->store);
{
int i;
- sat_free(data->keys);
+ solv_free(data->keys);
- sat_free(data->schemata);
- sat_free(data->schemadata);
- sat_free(data->schematahash);
+ solv_free(data->schemata);
+ solv_free(data->schemadata);
+ solv_free(data->schematahash);
stringpool_free(&data->spool);
dirpool_free(&data->dirpool);
- sat_free(data->mainschemaoffsets);
- sat_free(data->incoredata);
- sat_free(data->incoreoffset);
- sat_free(data->verticaloffset);
+ solv_free(data->mainschemaoffsets);
+ solv_free(data->incoredata);
+ solv_free(data->incoreoffset);
+ solv_free(data->verticaloffset);
repopagestore_free(&data->store);
- sat_free(data->vincore);
+ solv_free(data->vincore);
if (data->attrs)
for (i = 0; i < data->end - data->start; i++)
- sat_free(data->attrs[i]);
- sat_free(data->attrs);
+ solv_free(data->attrs[i]);
+ solv_free(data->attrs);
if (data->xattrs)
for (i = 0; i < data->nxattrs; i++)
- sat_free(data->xattrs[i]);
- sat_free(data->xattrs);
-
- sat_free(data->attrdata);
- sat_free(data->attriddata);
-}
+ solv_free(data->xattrs[i]);
+ solv_free(data->xattrs);
-Repodata *
-repodata_create(Repo *repo, int localpool)
-{
- Repodata *data;
+ solv_free(data->attrdata);
+ solv_free(data->attriddata);
+ solv_free(data->attrnum64data);
- repo->nrepodata++;
- repo->repodata = sat_realloc2(repo->repodata, repo->nrepodata, sizeof(*data));
- data = repo->repodata + repo->nrepodata - 1;
- repodata_initdata(data, repo, localpool);
- return data;
+ solv_free(data->dircache);
}
void
{
Repo *repo = data->repo;
int i = data - repo->repodata;
+ if (i == 0)
+ return;
repodata_freedata(data);
if (i < repo->nrepodata - 1)
- memmove(repo->repodata + i, repo->repodata + i + 1, (repo->nrepodata - 1 - i) * sizeof(Repodata));
+ {
+ /* whoa! this changes the repodataids! */
+ memmove(repo->repodata + i, repo->repodata + i + 1, (repo->nrepodata - 1 - i) * sizeof(Repodata));
+ for (; i < repo->nrepodata - 1; i++)
+ repo->repodata[i].repodataid = i;
+ }
repo->nrepodata--;
+ if (repo->nrepodata == 1)
+ {
+ repo->repodata = solv_free(repo->repodata);
+ repo->nrepodata = 0;
+ }
+}
+
+void
+repodata_empty(Repodata *data, int localpool)
+{
+ void (*loadcallback)(Repodata *) = data->loadcallback;
+ int state = data->state;
+ repodata_freedata(data);
+ repodata_initdata(data, data->repo, localpool);
+ data->state = state;
+ data->loadcallback = loadcallback;
}
if (!create)
return 0;
/* allocate new key */
- data->keys = sat_realloc2(data->keys, data->nkeys + 1, sizeof(Repokey));
+ data->keys = solv_realloc2(data->keys, data->nkeys + 1, sizeof(Repokey));
data->keys[data->nkeys++] = *key;
if (data->verticaloffset)
{
- data->verticaloffset = sat_realloc2(data->verticaloffset, data->nkeys, sizeof(Id));
+ data->verticaloffset = solv_realloc2(data->verticaloffset, data->nkeys, sizeof(Id));
data->verticaloffset[data->nkeys - 1] = 0;
}
data->keybits[(key->name >> 3) & (sizeof(data->keybits) - 1)] |= 1 << (key->name & 7);
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++)
+ data->schematahash = schematahash = solv_calloc(256, sizeof(Id));
+ 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);
+ data->schemadata = solv_extend_resize(data->schemadata, data->schemadatalen, sizeof(Id), SCHEMATADATA_BLOCK);
+ data->schemata = solv_extend_resize(data->schemata, data->nschemata, sizeof(Id), SCHEMATA_BLOCK);
}
for (sp = schema, len = 0, h = 0; *sp; len++)
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;
}
/* a new one */
if (!create)
return 0;
- data->schemadata = sat_extend(data->schemadata, data->schemadatalen, len, sizeof(Id), SCHEMATADATA_BLOCK);
- data->schemata = sat_extend(data->schemata, data->nschemata, 1, sizeof(Id), SCHEMATA_BLOCK);
+ data->schemadata = solv_extend(data->schemadata, data->schemadatalen, len, sizeof(Id), SCHEMATADATA_BLOCK);
+ data->schemata = solv_extend(data->schemata, data->nschemata, 1, sizeof(Id), SCHEMATA_BLOCK);
/* add schema */
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
void
repodata_free_schemahash(Repodata *data)
{
- data->schematahash = sat_free(data->schematahash);
+ data->schematahash = solv_free(data->schematahash);
/* shrink arrays */
- data->schemata = sat_realloc2(data->schemata, data->nschemata, sizeof(Id));
- data->schemadata = sat_realloc2(data->schemadata, data->schemadatalen, sizeof(Id));
+ data->schemata = solv_realloc2(data->schemata, data->nschemata, sizeof(Id));
+ data->schemadata = solv_realloc2(data->schemadata, data->schemadatalen, sizeof(Id));
}
* dir pool management
*/
+#ifndef HAVE_STRCHRNUL
+static inline const char *strchrnul(const char *str, char x)
+{
+ const char *p = strchr(str, x);
+ return p ? p : str + strlen(str);
+}
+#endif
+
+#define DIRCACHE_SIZE 41 /* < 1k */
+
+#ifdef DIRCACHE_SIZE
+struct dircache {
+ Id ids[DIRCACHE_SIZE];
+ char str[(DIRCACHE_SIZE * (DIRCACHE_SIZE - 1)) / 2];
+};
+#endif
+
Id
repodata_str2dir(Repodata *data, const char *dir, int create)
{
Id id, parent;
+#ifdef DIRCACHE_SIZE
+ const char *dirs;
+#endif
const char *dire;
parent = 0;
+ if (!*dir)
+ return 0;
while (*dir == '/' && dir[1] == '/')
dir++;
if (*dir == '/' && !dir[1])
return 1;
return dirpool_add_dir(&data->dirpool, 0, 1, create);
}
+#ifdef DIRCACHE_SIZE
+ dirs = dir;
+ if (data->dircache)
+ {
+ int l;
+ struct dircache *dircache = data->dircache;
+ l = strlen(dir);
+ while (l > 0)
+ {
+ if (l < DIRCACHE_SIZE && dircache->ids[l] && !memcmp(dircache->str + l * (l - 1) / 2, dir, l))
+ {
+ parent = dircache->ids[l];
+ dir += l;
+ if (!*dir)
+ return parent;
+ while (*dir == '/')
+ dir++;
+ break;
+ }
+ while (--l)
+ if (dir[l] == '/')
+ break;
+ }
+ }
+#endif
while (*dir)
{
dire = strchrnul(dir, '/');
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);
if (!parent)
return 0;
+#ifdef DIRCACHE_SIZE
+ if (!data->dircache)
+ data->dircache = solv_calloc(1, sizeof(struct dircache));
+ if (data->dircache)
+ {
+ int l = dire - dirs;
+ if (l < DIRCACHE_SIZE)
+ {
+ data->dircache->ids[l] = parent;
+ memcpy(data->dircache->str + l * (l - 1) / 2, dirs, l);
+ }
+ }
+#endif
if (!*dire)
break;
dir = dire + 1;
return parent;
}
+void
+repodata_free_dircache(Repodata *data)
+{
+ data->dircache = solv_free(data->dircache);
+}
+
const char *
repodata_dir2str(Repodata *data, Id did, const char *suf)
{
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 (keyname)
{
int i;
- for (i = 0; i < data->nkeys; i++)
+ for (i = 1; i < data->nkeys; i++)
if (keyname == data->keys[i].name)
break;
if (i == data->nkeys)
if (!*kp)
return 0;
*keypp = key = data->keys + *kp;
+ if (key->type == REPOKEY_TYPE_DELETED)
+ return 0;
if (key->type == REPOKEY_TYPE_VOID || key->type == REPOKEY_TYPE_CONSTANT || key->type == REPOKEY_TYPE_CONSTANTID)
return dp; /* no need to forward... */
dp = forward_to_key(data, *kp, keyp, dp);
return get_data(data, key, &dp, 0);
}
+Id
+repodata_lookup_type(Repodata *data, Id solvid, Id keyname)
+{
+ Id schema, *keyp, *kp;
+ if (!maybe_load_repodata(data, keyname))
+ return 0;
+ if (!solvid2data(data, solvid, &schema))
+ return 0;
+ keyp = data->schemadata + data->schemata[schema];
+ for (kp = keyp; *kp; kp++)
+ if (data->keys[*kp].name == keyname)
+ return data->keys[*kp].type;
+ return 0;
+}
Id
repodata_lookup_id(Repodata *data, Id solvid, Id keyname)
return id;
}
-Id
-repodata_globalize_id(Repodata *data, Id id, int create)
-{
- if (!id || !data || !data->localpool)
- return id;
- return str2id(data->repo->pool, stringpool_id2str(&data->spool, id), create);
-}
-
const char *
repodata_lookup_str(Repodata *data, Id solvid, Id keyname)
{
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
-repodata_lookup_num(Repodata *data, Id solvid, Id keyname, unsigned int *value)
+repodata_lookup_num(Repodata *data, Id solvid, Id keyname, unsigned long long *value)
{
unsigned char *dp;
Repokey *key;
- KeyValue kv;
+ unsigned int high, low;
*value = 0;
dp = find_key_data(data, solvid, keyname, &key);
if (!dp)
return 0;
- if (key->type == REPOKEY_TYPE_NUM
- || key->type == REPOKEY_TYPE_U32
- || key->type == REPOKEY_TYPE_CONSTANT)
+ switch (key->type)
{
- dp = data_fetch(dp, &kv, key);
- *value = kv.num;
+ case REPOKEY_TYPE_NUM:
+ data_read_num64(dp, &low, &high);
+ *value = (unsigned long long)high << 32 | low;
+ return 1;
+ case REPOKEY_TYPE_U32:
+ data_read_u32(dp, &low);
+ *value = low;
return 1;
+ case REPOKEY_TYPE_CONSTANT:
+ *value = key->size;
+ return 1;
+ default:
+ return 0;
}
- return 0;
}
int
dp = find_key_data(data, solvid, keyname, &key);
if (!dp)
return 0;
+ if (!(key->type == REPOKEY_TYPE_MD5 || key->type == REPOKEY_TYPE_SHA1 || key->type == REPOKEY_TYPE_SHA256))
+ return 0;
*typep = key->type;
return dp;
}
dp = find_key_data(data, solvid, keyname, &key);
if (!dp)
return 0;
+ if (key->type != REPOKEY_TYPE_IDARRAY && key->type != REPOKEY_TYPE_REL_IDARRAY)
+ return 0;
for (;;)
{
dp = data_read_ideof(dp, &id, &eof);
return 1;
}
+Id
+repodata_globalize_id(Repodata *data, Id id, int create)
+{
+ if (!id || !data || !data->localpool)
+ return id;
+ 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);
+}
+
+Id
+repodata_lookup_id_uninternalized(Repodata *data, Id solvid, Id keyname, Id voidid)
+{
+ Id *ap;
+ if (!data->attrs)
+ return 0;
+ ap = data->attrs[solvid - data->start];
+ if (!ap)
+ return 0;
+ for (; *ap; ap += 2)
+ {
+ if (data->keys[*ap].name != keyname)
+ continue;
+ if (data->keys[*ap].type == REPOKEY_TYPE_VOID)
+ return voidid;
+ if (data->keys[*ap].type == REPOKEY_TYPE_ID)
+ return ap[1];
+ return 0;
+ }
+ return 0;
+}
+
+
/************************************************************************
* data search
*/
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;
key = data->keys + keyid;
ddp = get_data(data, key, &dp, *keyp ? 1 : 0);
+ if (key->type == REPOKEY_TYPE_DELETED)
+ continue;
if (key->type == REPOKEY_TYPE_FLEXARRAY || key->type == REPOKEY_TYPE_FIXARRAY)
{
struct subschema_data subd;
* data iterator functions
*/
-static Repokey solvablekeys[RPM_RPMDBID - SOLVABLE_NAME + 1] = {
- { SOLVABLE_NAME, REPOKEY_TYPE_ID, 0, KEY_STORAGE_SOLVABLE },
- { SOLVABLE_ARCH, REPOKEY_TYPE_ID, 0, KEY_STORAGE_SOLVABLE },
- { SOLVABLE_EVR, REPOKEY_TYPE_ID, 0, KEY_STORAGE_SOLVABLE },
- { SOLVABLE_VENDOR, REPOKEY_TYPE_ID, 0, KEY_STORAGE_SOLVABLE },
- { SOLVABLE_PROVIDES, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
- { SOLVABLE_OBSOLETES, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
- { SOLVABLE_CONFLICTS, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
- { SOLVABLE_REQUIRES, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
- { SOLVABLE_RECOMMENDS, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
- { SOLVABLE_SUGGESTS, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
- { SOLVABLE_SUPPLEMENTS, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
- { SOLVABLE_ENHANCES, REPOKEY_TYPE_IDARRAY, 0, KEY_STORAGE_SOLVABLE },
- { RPM_RPMDBID, REPOKEY_TYPE_U32, 0, KEY_STORAGE_SOLVABLE },
-};
-
static inline Id *
solvabledata_fetch(Solvable *s, KeyValue *kv, Id keyname)
{
ma->matchdata = 0;
if ((flags & SEARCH_STRINGMASK) == SEARCH_REGEX)
{
- ma->matchdata = sat_calloc(1, sizeof(regex_t));
+ ma->matchdata = solv_calloc(1, sizeof(regex_t));
ma->error = regcomp((regex_t *)ma->matchdata, match, REG_EXTENDED | REG_NOSUB | REG_NEWLINE | ((flags & SEARCH_NOCASE) ? REG_ICASE : 0));
if (ma->error)
{
- sat_free(ma->matchdata);
+ solv_free(ma->matchdata);
ma->flags = (flags & ~SEARCH_STRINGMASK) | SEARCH_ERROR;
}
}
if ((ma->flags & SEARCH_STRINGMASK) == SEARCH_REGEX && ma->matchdata)
{
regfree(ma->matchdata);
- ma->matchdata = sat_free(ma->matchdata);
+ ma->matchdata = solv_free(ma->matchdata);
}
}
di_entersub,
di_leavesub,
- di_nextsolvableattr,
di_nextsolvablekey,
- di_entersolvablekey
+ di_entersolvablekey,
+ di_nextsolvableattr
};
-/* see repo.h for documentation */
+/* see dataiterator.h for documentation */
int
dataiterator_init(Dataiterator *di, Pool *pool, Repo *repo, Id p, Id keyname, const char *match, int flags)
{
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;
- di->repodataid = 0;
- if (!di->pool->nrepos)
+ di->repodataid = 1;
+ if (!di->pool->urepos)
{
di->state = di_bye;
return;
}
if (!repo)
{
- di->repoid = 0;
- di->repo = di->pool->repos[0];
+ di->repoid = 1;
+ di->repo = di->pool->repos[di->repoid];
}
di->state = di_enterrepo;
if (p)
Repodata *data = di->data;
if ((di->matcher.flags & SEARCH_COMPLETE_FILELIST) != 0)
- if (!di->matcher.match || (di->matcher.flags & (SEARCH_STRINGMASK|SEARCH_NOCASE)) != SEARCH_STRING || !repodata_filelistfilter_matches(di->data, di->matcher.match))
+ if (!di->matcher.match
+ || ((di->matcher.flags & (SEARCH_STRINGMASK|SEARCH_NOCASE)) != SEARCH_STRING
+ && (di->matcher.flags & (SEARCH_STRINGMASK|SEARCH_NOCASE)) != SEARCH_GLOB)
+ || !repodata_filelistfilter_matches(di->data, di->matcher.match))
needcomplete = 1;
if (data->state != REPODATA_AVAILABLE)
return needcomplete ? 1 : 0;
switch (di->state)
{
case di_enterrepo: di_enterrepo:
- if (!di->repo)
- goto di_bye;
- if (di->repo->disabled && !(di->flags & SEARCH_DISABLED_REPOS))
+ if (!di->repo || (di->repo->disabled && !(di->flags & SEARCH_DISABLED_REPOS)))
goto di_nextrepo;
if (!(di->flags & SEARCH_THISSOLVID))
{
/* FALLTHROUGH */
case di_entersolvable: di_entersolvable:
- if (di->repodataid >= 0)
+ if (di->repodataid)
{
- di->repodataid = 0; /* reset repodata iterator */
+ di->repodataid = 1; /* reset repodata iterator */
if (di->solvid > 0 && !(di->flags & SEARCH_NO_STORAGE_SOLVABLE) && (!di->keyname || (di->keyname >= SOLVABLE_NAME && di->keyname <= RPM_RPMDBID)) && di->nparents - di->rootlevel == di->nkeynames)
{
- di->key = solvablekeys + (di->keyname ? di->keyname - SOLVABLE_NAME : 0);
+ extern Repokey repo_solvablekeys[RPM_RPMDBID - SOLVABLE_NAME + 1];
+
+ di->key = repo_solvablekeys + (di->keyname ? di->keyname - SOLVABLE_NAME : 0);
di->data = 0;
goto di_entersolvablekey;
}
/* FALLTHROUGH */
case di_enterrepodata: di_enterrepodata:
- if (di->repodataid >= 0)
+ if (di->repodataid)
{
if (di->repodataid >= di->repo->nrepodata)
goto di_nextsolvable;
di->data = di->repo->repodata + di->repodataid;
}
- if (di->repodataid >= 0 && di->keyname == SOLVABLE_FILELIST && !dataiterator_filelistcheck(di))
+ if (di->repodataid && di->keyname == SOLVABLE_FILELIST && !dataiterator_filelistcheck(di))
goto di_nextrepodata;
if (!maybe_load_repodata(di->data, di->keyname))
goto di_nextrepodata;
di->ddp = get_data(di->data, di->key, &di->dp, di->keyp[1] && (!di->keyname || (di->flags & SEARCH_SUB) != 0) ? 1 : 0);
if (!di->ddp)
goto di_nextkey;
+ if (di->key->type == REPOKEY_TYPE_DELETED)
+ goto di_nextkey;
if (di->key->type == REPOKEY_TYPE_FIXARRAY || di->key->type == REPOKEY_TYPE_FLEXARRAY)
goto di_enterarray;
if (di->nkeynames && di->nparents - di->rootlevel < di->nkeynames)
/* FALLTHROUGH */
case di_nextrepodata: di_nextrepodata:
- if (di->repodataid >= 0 && ++di->repodataid < di->repo->nrepodata)
+ if (di->repodataid && ++di->repodataid < di->repo->nrepodata)
goto di_enterrepodata;
/* FALLTHROUGH */
/* FALLTHROUGH */
case di_nextrepo: di_nextrepo:
- if (di->repoid >= 0)
+ if (di->repoid > 0)
{
di->repoid++;
- di->repodataid = 0;
+ di->repodataid = 1;
if (di->repoid < di->pool->nrepos)
{
di->repo = di->pool->repos[di->repoid];
case di_enterarray: di_enterarray:
if (di->key->name == REPOSITORY_SOLVABLES)
goto di_nextkey;
- di->ddp = data_read_id(di->ddp, &di->kv.num);
+ di->ddp = data_read_id(di->ddp, (Id *)&di->kv.num);
di->kv.eof = 0;
di->kv.entry = -1;
/* FALLTHROUGH */
/* special solvable attr handling follows */
- case di_nextsolvableattr:
- di->kv.id = *di->idp++;
- di->kv.entry++;
- if (!*di->idp)
- {
- di->kv.eof = 1;
- di->state = di_nextsolvablekey;
- }
- break;
-
case di_nextsolvablekey: di_nextsolvablekey:
if (di->keyname || di->key->name == RPM_RPMDBID)
goto di_enterrepodata;
case di_entersolvablekey: di_entersolvablekey:
di->idp = solvabledata_fetch(di->pool->solvables + di->solvid, &di->kv, di->key->name);
- if (!di->idp || !di->idp[0])
+ if (!di->idp || !*di->idp)
goto di_nextsolvablekey;
- di->kv.id = di->idp[0];
- di->kv.num = di->idp[0];
- di->idp++;
- if (!di->kv.eof && !di->idp[0])
- di->kv.eof = 1;
- di->kv.entry = 0;
if (di->kv.eof)
- di->state = di_nextsolvablekey;
- else
- di->state = di_nextsolvableattr;
+ {
+ /* not an array */
+ di->kv.id = *di->idp;
+ di->kv.num = *di->idp; /* for rpmdbid */
+ di->kv.num2 = 0; /* for rpmdbid */
+ di->kv.entry = 0;
+ di->state = di_nextsolvablekey;
+ break;
+ }
+ di->kv.entry = -1;
+ /* FALLTHROUGH */
+
+ case di_nextsolvableattr:
+ di->state = di_nextsolvableattr;
+ di->kv.id = *di->idp++;
+ di->kv.entry++;
+ if (!*di->idp)
+ {
+ di->kv.eof = 1;
+ di->state = di_nextsolvablekey;
+ }
break;
+
}
if (di->matcher.match)
if (!datamatcher_match(&di->matcher, di->kv.str))
continue;
}
+ else
+ {
+ if (di->keyname == SOLVABLE_FILELIST && di->key->type == REPOKEY_TYPE_DIRSTRARRAY && (di->flags & SEARCH_FILES) != 0)
+ repodata_stringify(di->pool, di->data, di->key, &di->kv, di->flags);
+ }
/* found something! */
return 1;
}
dataiterator_skip_solvable(Dataiterator *di)
{
di->nparents = 0;
+ di->kv.parent = 0;
di->rootlevel = 0;
di->keyname = di->keynames[0];
di->state = di_nextsolvable;
dataiterator_skip_repo(Dataiterator *di)
{
di->nparents = 0;
+ di->kv.parent = 0;
di->rootlevel = 0;
di->keyname = di->keynames[0];
di->state = di_nextrepo;
dataiterator_jump_to_solvid(Dataiterator *di, Id solvid)
{
di->nparents = 0;
+ di->kv.parent = 0;
di->rootlevel = 0;
di->keyname = di->keynames[0];
if (solvid == SOLVID_POS)
di->state = di_bye;
return;
}
- di->repoid = -1;
+ di->repoid = 0;
di->data = di->repo->repodata + di->pool->pos.repodataid;
- di->repodataid = -1;
+ di->repodataid = 0;
di->solvid = solvid;
di->state = di_enterrepo;
di->flags |= SEARCH_THISSOLVID;
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)
+ if (!di->pool->urepos)
{
di->state = di_bye;
return;
}
- di->repo = di->pool->repos[0];
- di->repoid = 0;
+ di->repoid = 1;
+ di->repo = di->pool->repos[di->repoid];
}
- di->repodataid = 0;
+ di->repodataid = 1;
di->solvid = solvid;
if (solvid)
di->flags |= SEARCH_THISSOLVID;
dataiterator_jump_to_repo(Dataiterator *di, Repo *repo)
{
di->nparents = 0;
+ di->kv.parent = 0;
di->rootlevel = 0;
di->repo = repo;
- di->repoid = -1;
- di->repodataid = 0;
+ di->repoid = 0; /* 0 means stay at repo */
+ di->repodataid = 1;
di->solvid = 0;
di->flags &= ~SEARCH_THISSOLVID;
di->state = di_enterrepo;
int new = p - data->end + 1;
if (data->attrs)
{
- data->attrs = sat_extend(data->attrs, old, new, sizeof(Id *), REPODATA_BLOCK);
+ data->attrs = solv_extend(data->attrs, old, new, sizeof(Id *), REPODATA_BLOCK);
memset(data->attrs + old, 0, new * sizeof(Id *));
}
- data->incoreoffset = sat_extend(data->incoreoffset, old, new, sizeof(Id), REPODATA_BLOCK);
+ data->incoreoffset = solv_extend(data->incoreoffset, old, new, sizeof(Id), REPODATA_BLOCK);
memset(data->incoreoffset + old, 0, new * sizeof(Id));
data->end = p + 1;
}
int new = data->start - p;
if (data->attrs)
{
- data->attrs = sat_extend_resize(data->attrs, old + new, sizeof(Id *), REPODATA_BLOCK);
+ data->attrs = solv_extend_resize(data->attrs, old + new, sizeof(Id *), REPODATA_BLOCK);
memmove(data->attrs + new, data->attrs, old * sizeof(Id *));
memset(data->attrs, 0, new * sizeof(Id *));
}
- data->incoreoffset = sat_extend_resize(data->incoreoffset, old + new, sizeof(Id), REPODATA_BLOCK);
+ data->incoreoffset = solv_extend_resize(data->incoreoffset, old + new, sizeof(Id), REPODATA_BLOCK);
memmove(data->incoreoffset + new, data->incoreoffset, old * sizeof(Id));
memset(data->incoreoffset, 0, new * sizeof(Id));
data->start = p;
if (data->attrs)
{
for (i = 0; i < data->end - data->start; i++)
- sat_free(data->attrs[i]);
- data->attrs = sat_free(data->attrs);
+ solv_free(data->attrs[i]);
+ data->attrs = solv_free(data->attrs);
}
- data->incoreoffset = sat_free(data->incoreoffset);
+ data->incoreoffset = solv_free(data->incoreoffset);
data->start = data->end = 0;
return;
}
if (data->attrs)
{
for (i = end; i < data->end; i++)
- sat_free(data->attrs[i - data->start]);
- data->attrs = sat_extend_resize(data->attrs, end - data->start, sizeof(Id *), REPODATA_BLOCK);
+ solv_free(data->attrs[i - data->start]);
+ data->attrs = solv_extend_resize(data->attrs, end - data->start, sizeof(Id *), REPODATA_BLOCK);
}
if (data->incoreoffset)
- data->incoreoffset = sat_extend_resize(data->incoreoffset, end - data->start, sizeof(Id), REPODATA_BLOCK);
+ data->incoreoffset = solv_extend_resize(data->incoreoffset, end - data->start, sizeof(Id), REPODATA_BLOCK);
data->end = end;
}
return;
if (!data->incoreoffset)
{
- data->incoreoffset = sat_calloc_block(num, sizeof(Id), REPODATA_BLOCK);
+ data->incoreoffset = solv_calloc_block(num, sizeof(Id), REPODATA_BLOCK);
data->start = start;
data->end = start + num;
return;
#define REPODATA_ATTRS_BLOCK 31
#define REPODATA_ATTRDATA_BLOCK 1023
#define REPODATA_ATTRIDDATA_BLOCK 63
+#define REPODATA_ATTRNUM64DATA_BLOCK 15
Id
{
if (!data->nxattrs)
{
- data->xattrs = sat_calloc_block(1, sizeof(Id *), REPODATA_BLOCK);
- data->nxattrs = 2;
+ data->xattrs = solv_calloc_block(1, sizeof(Id *), REPODATA_BLOCK);
+ data->nxattrs = 2; /* -1: SOLVID_META */
}
- data->xattrs = sat_extend(data->xattrs, data->nxattrs, 1, sizeof(Id *), REPODATA_BLOCK);
+ data->xattrs = solv_extend(data->xattrs, data->nxattrs, 1, sizeof(Id *), REPODATA_BLOCK);
data->xattrs[data->nxattrs] = 0;
return -(data->nxattrs++);
}
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->xattrs = solv_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)
- data->attrs = sat_calloc_block(data->end - data->start, sizeof(Id *), REPODATA_BLOCK);
+ data->attrs = solv_calloc_block(data->end - data->start, sizeof(Id *), REPODATA_BLOCK);
return data->attrs + (handle - data->start);
}
break;
if (*pp)
{
- if (overwrite)
+ if (overwrite || data->keys[*pp].type == REPOKEY_TYPE_DELETED)
{
pp[0] = keyid;
pp[1] = val;
}
i = pp - ap;
}
- ap = sat_extend(ap, i, 3, sizeof(Id), REPODATA_ATTRS_BLOCK);
+ ap = solv_extend(ap, i, 3, sizeof(Id), REPODATA_ATTRS_BLOCK);
*app = ap;
pp = ap + i;
*pp++ = keyid;
}
void
-repodata_set_num(Repodata *data, Id solvid, Id keyname, unsigned int num)
+repodata_set_num(Repodata *data, Id solvid, Id keyname, unsigned long long num)
{
Repokey key;
key.name = keyname;
key.type = REPOKEY_TYPE_NUM;
key.size = 0;
key.storage = KEY_STORAGE_INCORE;
+ if (num >= 0x80000000)
+ {
+ data->attrnum64data = solv_extend(data->attrnum64data, data->attrnum64datalen, 1, sizeof(unsigned long long), REPODATA_ATTRNUM64DATA_BLOCK);
+ data->attrnum64data[data->attrnum64datalen] = num;
+ num = 0x80000000 | data->attrnum64datalen++;
+ }
repodata_set(data, solvid, &key, (Id)num);
}
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;
key.type = REPOKEY_TYPE_STR;
key.size = 0;
key.storage = KEY_STORAGE_INCORE;
- data->attrdata = sat_extend(data->attrdata, data->attrdatalen, l, 1, REPODATA_ATTRDATA_BLOCK);
+ data->attrdata = solv_extend(data->attrdata, data->attrdatalen, l, 1, REPODATA_ATTRDATA_BLOCK);
memcpy(data->attrdata + data->attrdatalen, str, l);
repodata_set(data, solvid, &key, data->attrdatalen);
data->attrdatalen += l;
}
+void
+repodata_set_binary(Repodata *data, Id solvid, Id keyname, void *buf, int len)
+{
+ Repokey key;
+ unsigned char *dp;
+
+ if (len < 0)
+ return;
+ key.name = keyname;
+ key.type = REPOKEY_TYPE_BINARY;
+ key.size = 0;
+ key.storage = KEY_STORAGE_INCORE;
+ data->attrdata = solv_extend(data->attrdata, data->attrdatalen, len + 5, 1, REPODATA_ATTRDATA_BLOCK);
+ dp = data->attrdata + data->attrdatalen;
+ if (len >= (1 << 14))
+ {
+ if (len >= (1 << 28))
+ *dp++ = (len >> 28) | 128;
+ if (len >= (1 << 21))
+ *dp++ = (len >> 21) | 128;
+ *dp++ = (len >> 14) | 128;
+ }
+ if (len >= (1 << 7))
+ *dp++ = (len >> 7) | 128;
+ *dp++ = len & 127;
+ if (len)
+ memcpy(dp, buf, len);
+ repodata_set(data, solvid, &key, data->attrdatalen);
+ data->attrdatalen = dp + len - data->attrdata;
+}
+
/* add an array element consisting of entrysize Ids to the repodata. modifies attriddata
- * so that the caller can append the new element there */
+ * so that the caller can append entrysize new elements plus the termination zero there */
static void
repodata_add_array(Repodata *data, Id handle, Id keyname, Id keytype, int entrysize)
{
if (handle == data->lasthandle && data->keys[data->lastkey].name == keyname && data->keys[data->lastkey].type == keytype && data->attriddatalen == data->lastdatalen)
{
/* great! just append the new data */
- data->attriddata = sat_extend(data->attriddata, data->attriddatalen, entrysize, sizeof(Id), REPODATA_ATTRIDDATA_BLOCK);
+ data->attriddata = solv_extend(data->attriddata, data->attriddatalen, entrysize, sizeof(Id), REPODATA_ATTRIDDATA_BLOCK);
data->attriddatalen--; /* overwrite terminating 0 */
data->lastdatalen += entrysize;
return;
ppp = repodata_get_attrp(data, handle);
pp = *ppp;
if (pp)
- for (; *pp; pp += 2)
- if (data->keys[*pp].name == keyname && data->keys[*pp].type == keytype)
- break;
- if (!pp || !*pp)
+ {
+ for (; *pp; pp += 2)
+ if (data->keys[*pp].name == keyname)
+ break;
+ }
+ if (!pp || !*pp || data->keys[*pp].type != keytype)
{
/* not found. allocate new key */
Repokey key;
+ Id keyid;
key.name = keyname;
key.type = keytype;
key.size = 0;
key.storage = KEY_STORAGE_INCORE;
- data->attriddata = sat_extend(data->attriddata, data->attriddatalen, entrysize + 1, sizeof(Id), REPODATA_ATTRIDDATA_BLOCK);
- repodata_set(data, handle, &key, data->attriddatalen);
- data->lasthandle = 0; /* next time... */
+ data->attriddata = solv_extend(data->attriddata, data->attriddatalen, entrysize + 1, sizeof(Id), REPODATA_ATTRIDDATA_BLOCK);
+ keyid = repodata_key2id(data, &key, 1);
+ repodata_insert_keyid(data, handle, keyid, data->attriddatalen, 1);
+ data->lasthandle = handle;
+ data->lastkey = keyid;
+ data->lastdatalen = data->attriddatalen + entrysize + 1;
return;
}
oldsize = 0;
if (ida + 1 == data->attriddata + data->attriddatalen)
{
/* this was the last entry, just append it */
- data->attriddata = sat_extend(data->attriddata, data->attriddatalen, entrysize, sizeof(Id), REPODATA_ATTRIDDATA_BLOCK);
+ data->attriddata = solv_extend(data->attriddata, data->attriddatalen, entrysize, sizeof(Id), REPODATA_ATTRIDDATA_BLOCK);
data->attriddatalen--; /* overwrite terminating 0 */
}
else
{
/* too bad. move to back. */
- data->attriddata = sat_extend(data->attriddata, data->attriddatalen, oldsize + entrysize + 1, sizeof(Id), REPODATA_ATTRIDDATA_BLOCK);
+ data->attriddata = solv_extend(data->attriddata, data->attriddatalen, oldsize + entrysize + 1, sizeof(Id), REPODATA_ATTRIDDATA_BLOCK);
memcpy(data->attriddata + data->attriddatalen, data->attriddata + pp[1], oldsize * sizeof(Id));
pp[1] = data->attriddatalen;
data->attriddatalen += oldsize;
Repokey key;
int l;
- if (!(l = sat_chksum_len(type)))
+ if (!(l = solv_chksum_len(type)))
return;
key.name = keyname;
key.type = type;
key.size = 0;
key.storage = KEY_STORAGE_INCORE;
- data->attrdata = sat_extend(data->attrdata, data->attrdatalen, l, 1, REPODATA_ATTRDATA_BLOCK);
+ data->attrdata = solv_extend(data->attrdata, data->attrdatalen, l, 1, REPODATA_ATTRDATA_BLOCK);
memcpy(data->attrdata + data->attrdatalen, str, l);
repodata_set(data, solvid, &key, data->attrdatalen);
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)
unsigned char buf[64];
int l;
- if (!(l = sat_chksum_len(type)))
+ if (!(l = solv_chksum_len(type)))
return;
- if (hexstr2bytes(buf, str, l) != l)
+ if (l > sizeof(buf) || solv_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)))
+ if (!(l = solv_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++)
;
- return p != evr && *p == ':' ? p + 1 : evr;
+ return p != evr && *p == ':' && p[1] ? p + 1 : evr;
}
void
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])
repodata_set_str(data, solvid, SOLVABLE_MEDIADIR, dir);
else
{
- char *dir2 = strdup(dir);
+ char *dir2 = solv_strdup(dir);
dir2[l] = 0;
repodata_set_str(data, solvid, SOLVABLE_MEDIADIR, dir2);
free(dir2);
}
}
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"))
{
repodata_set_str(data, solvid, SOLVABLE_MEDIAFILE, file);
}
+static inline void repodata_set_poolstrn(Repodata *data, Id solvid, Id keyname, const char *str, int l)
+{
+ Id id;
+ if (data->localpool)
+ id = stringpool_strn2id(&data->spool, str, l, 1);
+ else
+ id = pool_strn2id(data->repo->pool, str, l, 1);
+ repodata_set_id(data, solvid, keyname, id);
+}
+
+/* XXX: medianr is currently not stored */
+void
+repodata_set_deltalocation(Repodata *data, Id handle, int medianr, const char *dir, const char *file)
+{
+ int l = 0;
+ const char *evr, *suf, *s;
+
+ if (!dir)
+ {
+ if ((dir = strrchr(file, '/')) != 0)
+ {
+ l = dir - file;
+ dir = file;
+ file = dir + l + 1;
+ if (!l)
+ l++;
+ }
+ }
+ else
+ l = strlen(dir);
+ if (l >= 2 && dir[0] == '.' && dir[1] == '/' && (l == 2 || dir[2] != '/'))
+ {
+ dir += 2;
+ l -= 2;
+ }
+ if (l == 1 && dir[0] == '.')
+ l = 0;
+ if (dir && l)
+ repodata_set_poolstrn(data, handle, DELTA_LOCATION_DIR, dir, l);
+ evr = strchr(file, '-');
+ if (evr)
+ {
+ for (s = evr - 1; s > file; s--)
+ if (*s == '-')
+ {
+ evr = s;
+ break;
+ }
+ }
+ suf = strrchr(file, '.');
+ if (suf)
+ {
+ for (s = suf - 1; s > file; s--)
+ if (*s == '.')
+ {
+ suf = s;
+ break;
+ }
+ if (!strcmp(suf, ".delta.rpm") || !strcmp(suf, ".patch.rpm"))
+ {
+ /* We accept one more item as suffix. */
+ for (s = suf - 1; s > file; s--)
+ if (*s == '.')
+ {
+ suf = s;
+ break;
+ }
+ }
+ }
+ if (!evr)
+ suf = 0;
+ if (suf && evr && suf < evr)
+ suf = 0;
+ repodata_set_poolstrn(data, handle, DELTA_LOCATION_NAME, file, evr ? evr - file : strlen(file));
+ if (evr)
+ repodata_set_poolstrn(data, handle, DELTA_LOCATION_EVR, evr + 1, suf ? suf - evr - 1: strlen(evr + 1));
+ if (suf)
+ repodata_set_poolstr(data, handle, DELTA_LOCATION_SUFFIX, suf + 1);
+}
+
+void
+repodata_set_sourcepkg(Repodata *data, Id solvid, const char *sourcepkg)
+{
+ Pool *pool = data->repo->pool;
+ Solvable *s = pool->solvables + solvid;
+ const char *p, *sevr, *sarch, *name, *evr;
+
+ p = strrchr(sourcepkg, '.');
+ if (!p || strcmp(p, ".rpm") != 0)
+ {
+ if (*sourcepkg)
+ repodata_set_str(data, solvid, SOLVABLE_SOURCENAME, sourcepkg);
+ return;
+ }
+ p--;
+ while (p > sourcepkg && *p != '.')
+ p--;
+ if (*p != '.' || p == sourcepkg)
+ return;
+ sarch = p-- + 1;
+ while (p > sourcepkg && *p != '-')
+ p--;
+ if (*p != '-' || p == sourcepkg)
+ return;
+ p--;
+ while (p > sourcepkg && *p != '-')
+ p--;
+ if (*p != '-' || p == sourcepkg)
+ return;
+ sevr = p + 1;
+ pool = s->repo->pool;
+
+ name = pool_id2str(pool, s->name);
+ if (name && !strncmp(sourcepkg, name, sevr - sourcepkg - 1) && name[sevr - sourcepkg - 1] == 0)
+ repodata_set_void(data, solvid, SOLVABLE_SOURCENAME);
+ else
+ repodata_set_id(data, solvid, SOLVABLE_SOURCENAME, pool_strn2id(pool, sourcepkg, sevr - sourcepkg - 1, 1));
+
+ evr = evrid2vrstr(pool, s->evr);
+ if (evr && !strncmp(sevr, evr, sarch - sevr - 1) && evr[sarch - sevr - 1] == 0)
+ repodata_set_void(data, solvid, SOLVABLE_SOURCEEVR);
+ else
+ repodata_set_id(data, solvid, SOLVABLE_SOURCEEVR, pool_strn2id(pool, sevr, sarch - sevr - 1, 1));
+
+ if (!strcmp(sarch, "src.rpm"))
+ repodata_set_constantid(data, solvid, SOLVABLE_SOURCEARCH, ARCH_SRC);
+ else if (!strcmp(sarch, "nosrc.rpm"))
+ repodata_set_constantid(data, solvid, SOLVABLE_SOURCEARCH, ARCH_NOSRC);
+ else
+ repodata_set_constantid(data, solvid, SOLVABLE_SOURCEARCH, pool_strn2id(pool, sarch, strlen(sarch) - 4, 1));
+}
+
+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 = solv_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);
l = strlen(str) + 1;
- data->attrdata = sat_extend(data->attrdata, data->attrdatalen, l, 1, REPODATA_ATTRDATA_BLOCK);
+ data->attrdata = solv_extend(data->attrdata, data->attrdatalen, l, 1, REPODATA_ATTRDATA_BLOCK);
memcpy(data->attrdata + data->attrdatalen, str, l);
stroff = data->attrdatalen;
data->attrdatalen += l;
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);
}
data->attriddata[data->attriddatalen++] = 0;
}
-/* add all attrs from src to dest */
+void
+repodata_set_deleted_uninternalized(Repodata *data, Id solvid, Id keyname)
+{
+ Id *pp, *ap, **app;
+ app = repodata_get_attrp(data, solvid);
+ ap = *app;
+ if (!ap)
+ return;
+ for (; *ap; ap += 2)
+ if (data->keys[*ap].name == keyname)
+ break;
+ if (!*ap)
+ return;
+ pp = ap;
+ ap += 2;
+ for (; *ap; ap += 2)
+ {
+ if (data->keys[*ap].name == keyname)
+ continue;
+ *pp++ = ap[0];
+ *pp++ = ap[1];
+ }
+ *pp = 0;
+}
+
+/* XXX: does not work correctly, needs fix in iterators! */
+void
+repodata_set_deleted(Repodata *data, Id solvid, Id keyname)
+{
+ Repokey key;
+ key.name = keyname;
+ key.type = REPOKEY_TYPE_DELETED;
+ key.size = 0;
+ key.storage = KEY_STORAGE_INCORE;
+ repodata_set(data, solvid, &key, 0);
+}
+
+/* add all (uninternalized) attrs from src to dest */
void
repodata_merge_attrs(Repodata *data, Id dest, Id src)
{
Id *keyp;
- if (dest == src || !(keyp = data->attrs[src - data->start]))
+ if (dest == src || !data->attrs || !(keyp = data->attrs[src - data->start]))
return;
for (; *keyp; keyp += 2)
repodata_insert_keyid(data, dest, keyp[0], keyp[1], 0);
}
+/* add some (uninternalized) attrs from src to dest */
void
repodata_merge_some_attrs(Repodata *data, Id dest, Id src, Map *keyidmap, int overwrite)
{
Id *keyp;
- if (dest == src || !(keyp = data->attrs[src - data->start]))
+ if (dest == src || !data->attrs || !(keyp = data->attrs[src - data->start]))
return;
for (; *keyp; keyp += 2)
if (!keyidmap || MAPTST(keyidmap, keyp[0]))
repodata_insert_keyid(data, dest, keyp[0], keyp[1], overwrite);
}
+/* swap (uninternalized) attrs from src and dest */
+void
+repodata_swap_attrs(Repodata *data, Id dest, Id src)
+{
+ Id *tmpattrs;
+ if (!data->attrs || dest == src)
+ return;
+ tmpattrs = data->attrs[dest - data->start];
+ data->attrs[dest - data->start] = data->attrs[src - data->start];
+ data->attrs[src - data->start] = tmpattrs;
+}
/**********************************************************************/
-/* TODO: unify with repo_write! */
+/* TODO: unify with repo_write and repo_solv! */
#define EXTDATA_BLOCK 1023
};
static void
-data_addid(struct extdata *xd, Id x)
+data_addid(struct extdata *xd, Id sx)
{
+ unsigned int x = (unsigned int)sx;
unsigned char *dp;
- xd->buf = sat_extend(xd->buf, xd->len, 5, 1, EXTDATA_BLOCK);
+
+ xd->buf = solv_extend(xd->buf, xd->len, 5, 1, EXTDATA_BLOCK);
dp = xd->buf + xd->len;
if (x >= (1 << 14))
}
static void
-data_addideof(struct extdata *xd, Id x, int eof)
+data_addid64(struct extdata *xd, unsigned long long x)
{
- if (x >= 64)
- x = (x & 63) | ((x & ~63) << 1);
- data_addid(xd, (eof ? x: x | 64));
+ if (x >= 0x100000000)
+ {
+ if ((x >> 35) != 0)
+ {
+ data_addid(xd, (Id)(x >> 35));
+ xd->buf[xd->len - 1] |= 128;
+ }
+ data_addid(xd, (Id)((unsigned int)x | 0x80000000));
+ xd->buf[xd->len - 5] = (x >> 28) | 128;
+ }
+ else
+ data_addid(xd, (Id)x);
+}
+
+static void
+data_addideof(struct extdata *xd, Id sx, int eof)
+{
+ unsigned int x = (unsigned int)sx;
+ unsigned char *dp;
+
+ xd->buf = solv_extend(xd->buf, xd->len, 5, 1, EXTDATA_BLOCK);
+ dp = xd->buf + xd->len;
+
+ if (x >= (1 << 13))
+ {
+ if (x >= (1 << 27))
+ *dp++ = (x >> 27) | 128;
+ if (x >= (1 << 20))
+ *dp++ = (x >> 20) | 128;
+ *dp++ = (x >> 13) | 128;
+ }
+ if (x >= (1 << 6))
+ *dp++ = (x >> 6) | 128;
+ *dp++ = eof ? (x & 63) : (x & 63) | 64;
+ xd->len = dp - xd->buf;
}
static void
data_addblob(struct extdata *xd, unsigned char *blob, int len)
{
- xd->buf = sat_extend(xd->buf, xd->len, len, 1, EXTDATA_BLOCK);
+ xd->buf = solv_extend(xd->buf, xd->len, len, 1, EXTDATA_BLOCK);
memcpy(xd->buf + xd->len, blob, len);
xd->len += 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;
case REPOKEY_TYPE_SHA256:
data_addblob(xd, data->attrdata + val, SIZEOF_SHA256);
break;
- case REPOKEY_TYPE_ID:
case REPOKEY_TYPE_NUM:
+ if (val & 0x80000000)
+ {
+ data_addid64(xd, data->attrnum64data[val ^ 0x80000000]);
+ break;
+ }
+ /* FALLTHROUGH */
+ case REPOKEY_TYPE_ID:
case REPOKEY_TYPE_DIR:
data_addid(xd, val);
break;
+ case REPOKEY_TYPE_BINARY:
+ {
+ Id len;
+ unsigned char *dp = data_read_id(data->attrdata + val, &len);
+ dp += (unsigned int)len;
+ data_addblob(xd, data->attrdata + val, dp - (data->attrdata + val));
+ }
+ break;
case REPOKEY_TYPE_IDARRAY:
for (ida = data->attriddata + val; *ida; ida++)
data_addideof(xd, ida[0], ida[1] ? 0 : 1);
schemaid = 0;
for (ida = data->attriddata + val; *ida; ida++)
{
-#if 0
- fprintf(stderr, "serialize struct %d\n", *ida);
-#endif
+ Id *kp;
sp = schema;
- Id *kp = data->xattrs[-*ida];
+ 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);
else if (schemaid != repodata_schema2id(data, schema, 0))
{
- pool_debug(data->repo->pool, SAT_FATAL, "fixarray substructs with different schemas\n");
+ pool_debug(data->repo->pool, SOLV_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;
}
default:
- pool_debug(data->repo->pool, SAT_FATAL, "don't know how to handle type %d\n", key->type);
+ pool_debug(data->repo->pool, SOLV_FATAL, "don't know how to handle type %d\n", key->type);
exit(1);
}
if (key->storage == KEY_STORAGE_VERTICAL_OFFSET)
solvkey.storage = KEY_STORAGE_INCORE;
solvkeyid = repodata_key2id(data, &solvkey, data->end != data->start ? 1 : 0);
- schema = sat_malloc2(data->nkeys, sizeof(Id));
- seen = sat_malloc2(data->nkeys, sizeof(Id));
+ schema = solv_malloc2(data->nkeys, sizeof(Id));
+ seen = solv_malloc2(data->nkeys, sizeof(Id));
/* Merge the data already existing (in data->schemata, ->incoredata and
friends) with the new attributes in data->attrs[]. */
data_addid(&newincore, 0); /* start data at offset 1 */
data->mainschema = 0;
- data->mainschemaoffsets = sat_free(data->mainschemaoffsets);
+ data->mainschemaoffsets = solv_free(data->mainschemaoffsets);
/* join entry data */
/* we start with the meta data, entry -1 */
{
if (seen[*keyp])
{
- pool_debug(data->repo->pool, SAT_FATAL, "Inconsistent old data (key occured twice).\n");
+ pool_debug(data->repo->pool, SOLV_FATAL, "Inconsistent old data (key occured twice).\n");
exit(1);
}
seen[*keyp] = -1;
if (entry == -1)
{
data->mainschema = schemaid;
- data->mainschemaoffsets = sat_calloc(sp - schema, sizeof(Id));
+ data->mainschemaoffsets = solv_calloc(sp - schema, sizeof(Id));
}
keypstart = data->schemadata + data->schemata[schemaid];
for (keyp = keypstart; *keyp; keyp++)
}
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)
dp = ndp;
}
if (entry >= 0 && data->attrs && data->attrs[entry])
- data->attrs[entry] = sat_free(data->attrs[entry]);
+ data->attrs[entry] = solv_free(data->attrs[entry]);
}
/* free all xattrs */
for (entry = 0; entry < data->nxattrs; entry++)
if (data->xattrs[entry])
- sat_free(data->xattrs[entry]);
- data->xattrs = sat_free(data->xattrs);
+ solv_free(data->xattrs[entry]);
+ data->xattrs = solv_free(data->xattrs);
data->nxattrs = 0;
data->lasthandle = 0;
data->lastkey = 0;
data->lastdatalen = 0;
- sat_free(schema);
- sat_free(seen);
+ solv_free(schema);
+ solv_free(seen);
repodata_free_schemahash(data);
- sat_free(data->incoredata);
+ solv_free(data->incoredata);
data->incoredata = newincore.buf;
data->incoredatalen = newincore.len;
data->incoredatafree = 0;
- sat_free(data->vincore);
+ solv_free(data->vincore);
data->vincore = newvincore.buf;
data->vincorelen = newvincore.len;
- data->attrs = sat_free(data->attrs);
- data->attrdata = sat_free(data->attrdata);
- data->attriddata = sat_free(data->attriddata);
+ data->attrs = solv_free(data->attrs);
+ data->attrdata = solv_free(data->attrdata);
+ data->attriddata = solv_free(data->attriddata);
+ data->attrnum64data = solv_free(data->attrnum64data);
data->attrdatalen = 0;
data->attriddatalen = 0;
+ data->attrnum64datalen = 0;
}
void
{
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);
- if (!r)
- data->state = REPODATA_ERROR;
+
+ /* restore tmp space */
+ for (i = 0; i < POOL_TMPSPACEBUF; i++)
+ solv_free(pool->tmpspace.buf[i]);
+ pool->tmpspace = oldtmpspace;
+
+ data->state = r ? REPODATA_AVAILABLE : REPODATA_ERROR;
}
void
dataiterator_free(&di);
if (!cnt)
return;
- stubdataids = sat_calloc(cnt, sizeof(*stubdataids));
+ stubdataids = solv_calloc(cnt, sizeof(*stubdataids));
for (i = 0; i < cnt; i++)
{
sdata = repo_add_repodata(repo, 0);
repodata_set_void(sdata, SOLVID_META, di.key->name);
break;
case REPOKEY_TYPE_NUM:
- repodata_set_num(sdata, SOLVID_META, di.key->name, di.kv.num);
+ repodata_set_num(sdata, SOLVID_META, di.key->name, SOLV_KV_NUM64(&di.kv));
break;
case REPOKEY_TYPE_MD5:
case REPOKEY_TYPE_SHA1:
xkey.name = xkeyname;
xkey.type = di.kv.id;
xkey.storage = KEY_STORAGE_INCORE;
- xkey.size = 0;
+ xkey.size = 0;
repodata_key2id(sdata, &xkey, 1);
xkeyname = 0;
}
+ default:
+ break;
}
}
dataiterator_free(&di);
for (i = 0; i < cnt; i++)
repodata_internalize(repo->repodata + stubdataids[i]);
- sat_free(stubdataids);
+ solv_free(stubdataids);
+}
+
+unsigned int
+repodata_memused(Repodata *data)
+{
+ return data->incoredatalen + data->vincorelen;
}
/*