have attributes, but are not solvables). The usual functions interpret
negative entry numbers as those (positive ones are solvable IDs). I'll
probably refine the code some more, hence it's work in progress.
susetags2repo: Parse also a "=Lan:" tag, which can be injected
externally when multiple language tag files are catted together.
#define SOLV_VERSION_4 4
#define SOLV_VERSION_5 5
#define SOLV_VERSION_6 6
#define SOLV_VERSION_4 4
#define SOLV_VERSION_5 5
#define SOLV_VERSION_6 6
+#define SOLV_VERSION_7 7
#define SOLV_FLAG_PREFIX_POOL 4
#define SOLV_FLAG_PREFIX_POOL 4
KeyValue kv;
Pool *pool = repo->pool;
Repodata *data;
KeyValue kv;
Pool *pool = repo->pool;
Repodata *data;
- s = pool->solvables + p;
+ else if (p < 0)
+ /* The callback only supports solvables, so we can't iterate over the
+ extra things. */
+ return;
flags = md->flags;
if (!(flags & SEARCH_NO_STORAGE_SOLVABLE))
{
flags = md->flags;
if (!(flags & SEARCH_NO_STORAGE_SOLVABLE))
{
+ s = pool->solvables + p;
switch(keyname)
{
case 0:
switch(keyname)
{
case 0:
/* FIXME: enter nice code here */
for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
/* FIXME: enter nice code here */
for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
- if (p >= data->start && p < data->end)
+ if ((p < 0 && (-1 - p) >= data->extrastart && (-1 - p) < (data->extrastart + data->nextra))
+ || (p >= 0 && p >= data->start && p < data->end))
+ return data;
+ if (p < 0)
+ {
+ data = repo->repodata;
+ if (data)
+ {
+ for (i = 1; i < repo->nrepodata; i++)
+ if (data->extrastart + data->nextra
+ > repo->repodata[i].extrastart + repo->repodata[i].nextra)
+ data = repo->repodata + i;
+ }
+ else
+ data = repo_add_repodata(repo, 0);
+ repodata_extend_extra(data, (-1 - p) - data->extrastart + 1);
+ if (-p > repo->nextra)
+ repo->nextra = -p;
for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
if (p == data->end)
break;
for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
if (p == data->end)
break;
repo_set_id(Repo *repo, Id p, Id keyname, Id id)
{
Repodata *data = repo_findrepodata(repo, p, keyname);
repo_set_id(Repo *repo, Id p, Id keyname, Id id)
{
Repodata *data = repo_findrepodata(repo, p, keyname);
- repodata_set_id(data, p - data->start, keyname, id);
+ if (p < 0)
+ /* This is -1 - ((-1 - p) - data->extrastart). */
+ p = p + data->extrastart;
+ else
+ p = p - data->start;
+ repodata_set_id(data, p, keyname, id);
}
void
repo_set_num(Repo *repo, Id p, Id keyname, Id num)
{
Repodata *data = repo_findrepodata(repo, p, keyname);
}
void
repo_set_num(Repo *repo, Id p, Id keyname, Id num)
{
Repodata *data = repo_findrepodata(repo, p, keyname);
- repodata_set_num(data, p - data->start, keyname, num);
+ if (p < 0)
+ p = p + data->extrastart;
+ else
+ p = p - data->start;
+ repodata_set_num(data, p, keyname, num);
}
void
repo_set_str(Repo *repo, Id p, Id keyname, const char *str)
{
Repodata *data = repo_findrepodata(repo, p, keyname);
}
void
repo_set_str(Repo *repo, Id p, Id keyname, const char *str)
{
Repodata *data = repo_findrepodata(repo, p, keyname);
- repodata_set_str(data, p - data->start, keyname, str);
+ if (p < 0)
+ p = p + data->extrastart;
+ else
+ p = p - data->start;
+ repodata_set_str(data, p, keyname, str);
}
void
repo_set_poolstr(Repo *repo, Id p, Id keyname, const char *str)
{
Repodata *data = repo_findrepodata(repo, p, keyname);
}
void
repo_set_poolstr(Repo *repo, Id p, Id keyname, const char *str)
{
Repodata *data = repo_findrepodata(repo, p, keyname);
- repodata_set_poolstr(data, p - data->start, keyname, str);
+ if (p < 0)
+ p = p + data->extrastart;
+ else
+ p = p - data->start;
+ repodata_set_poolstr(data, p, keyname, str);
Repodata *data;
for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
Repodata *data;
for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
+ if (data->attrs || data->extraattrs)
repodata_internalize(data);
}
repodata_internalize(data);
}
int start; /* start of this repo solvables within pool->solvables */
int end; /* last solvable + 1 of this repo */
int nsolvables; /* number of solvables repo is contributing to pool */
int start; /* start of this repo solvables within pool->solvables */
int end; /* last solvable + 1 of this repo */
int nsolvables; /* number of solvables repo is contributing to pool */
+ int nextra; /* number of extra objects (non-solvables) */
int priority; /* priority of this repo */
int priority; /* priority of this repo */
#define SEARCH_NOCASE (1<<8)
#define SEARCH_NO_STORAGE_SOLVABLE (1<<9)
#define SEARCH_NOCASE (1<<8)
#define SEARCH_NO_STORAGE_SOLVABLE (1<<9)
+#define SEARCH_EXTRA (1<<10)
/* Internal */
#define __SEARCH_ONESOLVABLE (1 << 31)
/* Internal */
#define __SEARCH_ONESOLVABLE (1 << 31)
Pool *pool = repo->pool;
int i, l;
unsigned int numid, numrel, numdir, numsolv;
Pool *pool = repo->pool;
int i, l;
unsigned int numid, numrel, numdir, numsolv;
- unsigned int numkeys, numschemata, numinfo;
+ unsigned int numkeys, numschemata, numinfo, numextra;
Offset sizeid;
Offset *str; /* map Id -> Offset into string space */
Offset sizeid;
Offset *str; /* map Id -> Offset into string space */
{
case SOLV_VERSION_6:
break;
{
case SOLV_VERSION_6:
break;
+ case SOLV_VERSION_7:
+ break;
default:
pool_debug(pool, SAT_ERROR, "unsupported SOLV version\n");
return SOLV_ERROR_UNSUPPORTED;
default:
pool_debug(pool, SAT_ERROR, "unsupported SOLV version\n");
return SOLV_ERROR_UNSUPPORTED;
numkeys = read_u32(&data);
numschemata = read_u32(&data);
numinfo = read_u32(&data);
numkeys = read_u32(&data);
numschemata = read_u32(&data);
numinfo = read_u32(&data);
+ if (solvversion > SOLV_VERSION_6)
+ numextra = read_u32(&data);
+ else
+ numextra = 0;
solvflags = read_u32(&data);
if (numdir && numdir < 2)
solvflags = read_u32(&data);
if (numdir && numdir < 2)
pool_debug(pool, SAT_ERROR, "unequal number of solvables in a store\n");
return SOLV_ERROR_CORRUPT;
}
pool_debug(pool, SAT_ERROR, "unequal number of solvables in a store\n");
return SOLV_ERROR_CORRUPT;
}
+ if (parent->nextra != numextra)
+ {
+ pool_debug(pool, SAT_ERROR, "unequal number of non-solvables in a store\n");
+ return SOLV_ERROR_CORRUPT;
+ }
if (numinfo)
{
pool_debug(pool, SAT_ERROR, "info blocks are forbidden in a store\n");
if (numinfo)
{
pool_debug(pool, SAT_ERROR, "info blocks are forbidden in a store\n");
size_idarray += keys[i].size;
}
size_idarray += keys[i].size;
}
+ if (numsolv || numextra)
{
maxsize = read_id(&data, 0);
allsize = read_id(&data, 0);
{
maxsize = read_id(&data, 0);
allsize = read_id(&data, 0);
+ if (numextra)
+ {
+ data.extrastart = repo->nextra;
+ repodata_extend_extra(&data, numextra);
+ repo->nextra += numextra;
+ for (i = oldnrepodata; i < repo->nrepodata; i++)
+ {
+ repo->repodata[i].extrastart = data.extrastart;
+ repo->repodata[i].nextra = data.nextra;
+ }
+ }
+
if (have_xdata)
{
/* reserve one byte so that all offsets are not zero */
if (have_xdata)
{
/* reserve one byte so that all offsets are not zero */
left = 0;
buf = sat_calloc(maxsize + 4, 1);
dp = buf;
left = 0;
buf = sat_calloc(maxsize + 4, 1);
dp = buf;
- for (i = 0; i < numsolv; i++, s++)
+ for (i = 0; i < numsolv + numextra; i++, s++)
{
Id *keyp;
if (data.error)
{
Id *keyp;
if (data.error)
dp = data_read_id_max(dp, &id, 0, numschemata, &data.error);
if (have_xdata)
{
dp = data_read_id_max(dp, &id, 0, numschemata, &data.error);
if (have_xdata)
{
- data.incoreoffset[i] = data.incoredatalen;
+ if (i < numsolv)
+ data.incoreoffset[i] = data.incoredatalen;
+ else
+ data.extraoffset[i - numsolv] = data.incoredatalen;
incore_add_id(&data, id);
}
incore_add_id(&data, id);
}
+ if (i >= numsolv)
+ s = 0;
+#if 0
+ if (i < numsolv)
+ fprintf(stderr, "solv %d: schema %d\n", i, id);
+ else
+ fprintf(stderr, "extra %d: schema %d\n", i - numsolv, id);
+#endif
keyp = schemadata + schemata[id];
while ((key = *keyp++) != 0)
{
keyp = schemadata + schemata[id];
while ((key = *keyp++) != 0)
{
id = keys[key].name;
#if 0
id = keys[key].name;
#if 0
-fprintf(stderr, "solv %d name %d type %d class %d\n", i, id, keys[key].type, keys[key].storage);
+ if (i < numsolv)
+ fprintf(stderr, "solv %d name %d type %d class %d\n", i, id, keys[key].type, keys[key].storage);
+ else
+ fprintf(stderr, "extra %d name %d type %d class %d\n", i - numsolv, id, keys[key].type, keys[key].storage);
#endif
if (keys[key].storage == KEY_STORAGE_VERTICAL_OFFSET)
{
#endif
if (keys[key].storage == KEY_STORAGE_VERTICAL_OFFSET)
{
data->schemadatalen = 1;
data->start = repo->start;
data->end = repo->end;
data->schemadatalen = 1;
data->start = repo->start;
data->end = repo->end;
+ data->nextra = repo->nextra;
+ data->extrastart = 0;
data->incoreoffset = sat_extend_resize(0, data->end - data->start, sizeof(Id), REPODATA_BLOCK);
data->incoreoffset = sat_extend_resize(0, data->end - data->start, sizeof(Id), REPODATA_BLOCK);
+ data->extraoffset = sat_extend_resize(0, repo->nextra, sizeof(Id), REPODATA_BLOCK);
sat_free(data->incoredata);
sat_free(data->incoreoffset);
sat_free(data->incoredata);
sat_free(data->incoreoffset);
+ sat_free(data->extraoffset);
sat_free(data->verticaloffset);
sat_free(data->blob_store);
sat_free(data->verticaloffset);
sat_free(data->blob_store);
sat_free(data->vincore);
sat_free(data->attrs);
sat_free(data->vincore);
sat_free(data->attrs);
+ sat_free(data->extraattrs);
sat_free(data->attrdata);
sat_free(data->attriddata);
sat_free(data->attrdata);
sat_free(data->attriddata);
+static inline unsigned char*
+entry2data(Repodata *data, Id entry)
+{
+ if (entry < 0)
+ return data->incoredata + data->extraoffset[-1 - entry];
+ else
+ return data->incoredata + data->incoreoffset[entry];
+}
+
Id
repodata_lookup_id(Repodata *data, Id entry, Id keyid)
{
Id
repodata_lookup_id(Repodata *data, Id entry, Id keyid)
{
if (!maybe_load_repodata(data, &keyid))
return 0;
if (!maybe_load_repodata(data, &keyid))
return 0;
- dp = data->incoredata + data->incoreoffset[entry];
+ dp = entry2data(data, entry);
dp = data_read_id(dp, &schema);
/* make sure the schema of this solvable contains the key */
for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
dp = data_read_id(dp, &schema);
/* make sure the schema of this solvable contains the key */
for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
if (!maybe_load_repodata(data, &keyid))
return 0;
if (!maybe_load_repodata(data, &keyid))
return 0;
- dp = data->incoredata + data->incoreoffset[entry];
+ dp = entry2data(data, entry);
dp = data_read_id(dp, &schema);
/* make sure the schema of this solvable contains the key */
for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
dp = data_read_id(dp, &schema);
/* make sure the schema of this solvable contains the key */
for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
if (!maybe_load_repodata(data, &keyid))
return 0;
if (!maybe_load_repodata(data, &keyid))
return 0;
- dp = data->incoredata + data->incoreoffset[entry];
+ dp = entry2data(data, entry);
dp = data_read_id(dp, &schema);
/* make sure the schema of this solvable contains the key */
for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
dp = data_read_id(dp, &schema);
/* make sure the schema of this solvable contains the key */
for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
unsigned char *dp;
if (!maybe_load_repodata(data, &keyid))
return 0;
unsigned char *dp;
if (!maybe_load_repodata(data, &keyid))
return 0;
- dp = data->incoredata + data->incoreoffset[entry];
+ dp = entry2data(data, entry);
dp = data_read_id(dp, &schema);
for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
if (!*keyp)
dp = data_read_id(dp, &schema);
for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
if (!*keyp)
if (!maybe_load_repodata(data, &keyid))
return 0;
if (!maybe_load_repodata(data, &keyid))
return 0;
- dp = data->incoredata + data->incoreoffset[entry];
+ dp = entry2data(data, entry);
dp = data_read_id(dp, &schema);
for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
if (!*keyp)
dp = data_read_id(dp, &schema);
for (keyp = data->schemadata + data->schemata[schema]; *keyp != keyid; keyp++)
if (!*keyp)
- if (!maybe_load_repodata(data, 0))
+ if (entry < 0
+ || !maybe_load_repodata(data, 0))
- dp = data->incoredata + data->incoreoffset[entry];
+ dp = entry2data(data, entry);
dp = data_read_id(dp, &schema);
keyp = data->schemadata + data->schemata[schema];
if (keyname)
dp = data_read_id(dp, &schema);
keyp = data->schemadata + data->schemata[schema];
if (keyname)
- unsigned char *dp = data->incoredata + data->incoreoffset[di->solvid - data->start];
+ unsigned char *dp = data->incoredata;
+ if (di->solvid >= 0)
+ dp += data->incoreoffset[di->solvid - data->start];
+ else
+ dp += data->extraoffset[-1 - di->solvid - data->extrastart];
dp = data_read_id(dp, &schema);
Id *keyp = data->schemadata + data->schemata[schema];
if (keyname)
dp = data_read_id(dp, &schema);
Id *keyp = data->schemadata + data->schemata[schema];
if (keyname)
else
{
di->solvid = repo->start - 1;
else
{
di->solvid = repo->start - 1;
+ if (di->solvid < 0)
+ {
+ fprintf(stderr, "A repo contains the NULL solvable!\n");
+ exit(1);
+ }
di->data = repo->repodata + repo->nrepodata - 1;
di->state = 0;
}
di->data = repo->repodata + repo->nrepodata - 1;
di->state = 0;
}
{
if (di->flags & __SEARCH_ONESOLVABLE)
return 0;
{
if (di->flags & __SEARCH_ONESOLVABLE)
return 0;
- while (++di->solvid < repo->end)
- if (repo->pool->solvables[di->solvid].repo == repo)
- break;
- if (di->solvid >= repo->end)
- return 0;
+ if (di->solvid >= 0)
+ {
+ while (++di->solvid < repo->end)
+ if (repo->pool->solvables[di->solvid].repo == repo)
+ break;
+ if (di->solvid >= repo->end)
+ {
+ if (!(di->flags & SEARCH_EXTRA))
+ return 0;
+ di->solvid = -1;
+ if (di->solvid < -repo->nextra)
+ return 0;
+ }
+ }
+ else
+ {
+ --di->solvid;
+ if (di->solvid < -repo->nextra)
+ return 0;
+ }
di->data = repo->repodata - 1;
di->data = repo->repodata - 1;
- if (di->flags & SEARCH_NO_STORAGE_SOLVABLE)
+ if (di->solvid < 0
+ || (di->flags & SEARCH_NO_STORAGE_SOLVABLE))
continue;
static Id zeroid = 0;
di->keyp = &zeroid;
di->state = 1;
goto restart;
}
continue;
static Id zeroid = 0;
di->keyp = &zeroid;
di->state = 1;
goto restart;
}
- if (di->solvid >= data->start && di->solvid < data->end)
+ if ((di->solvid < 0 && (-1 - di->solvid) >= data->extrastart && (-1 - di->solvid) < (data->extrastart + data->nextra))
+ || (di->solvid >= 0 && di->solvid >= data->start && di->solvid < data->end))
{
dataiterator_newdata(di);
if (di->nextkeydp)
{
dataiterator_newdata(di);
if (di->nextkeydp)
+repodata_extend_extra(Repodata *data, int nextra)
+{
+ if (nextra <= data->nextra)
+ return;
+ if (data->extraattrs)
+ {
+ data->extraattrs = sat_extend(data->extraattrs, data->nextra, nextra - data->nextra, sizeof(Id *), REPODATA_BLOCK);
+ memset(data->extraattrs + data->nextra, 0, (nextra - data->nextra) * sizeof (Id *));
+ }
+ data->extraoffset = sat_extend(data->extraoffset, data->nextra, nextra - data->nextra, sizeof(Id), REPODATA_BLOCK);
+ memset(data->extraoffset + data->nextra, 0, (nextra - data->nextra) * sizeof(Id));
+ data->nextra = nextra;
+}
+
+void
repodata_extend_block(Repodata *data, Id start, Id num)
{
if (!num)
repodata_extend_block(Repodata *data, Id start, Id num)
{
if (!num)
repodata_insert_keyid(Repodata *data, Id entry, Id keyid, Id val, int overwrite)
{
Id *pp;
repodata_insert_keyid(Repodata *data, Id entry, Id keyid, Id val, int overwrite)
{
Id *pp;
+ if (!data->attrs && entry >= 0)
{
data->attrs = sat_calloc_block(data->end - data->start, sizeof(Id *),
REPODATA_BLOCK);
}
{
data->attrs = sat_calloc_block(data->end - data->start, sizeof(Id *),
REPODATA_BLOCK);
}
+ else if (!data->extraattrs && entry < 0)
+ data->extraattrs = sat_calloc_block(data->nextra, sizeof(Id *), REPODATA_BLOCK);
+ if (entry < 0)
+ ap = data->extraattrs[-1 - entry];
+ else
+ ap = data->attrs[entry];
- if (data->attrs[entry])
- for (pp = data->attrs[entry]; *pp; pp += 2)
+ for (pp = ap; *pp; pp += 2)
/* Determine equality based on the name only, allows us to change
type (when overwrite is set), and makes TYPE_CONSTANT work. */
if (data->keys[*pp].name == data->keys[keyid].name)
/* Determine equality based on the name only, allows us to change
type (when overwrite is set), and makes TYPE_CONSTANT work. */
if (data->keys[*pp].name == data->keys[keyid].name)
- i = pp - data->attrs[entry];
- data->attrs[entry] = sat_extend(data->attrs[entry], i, 3, sizeof(Id), REPODATA_ATTRS_BLOCK);
- pp = data->attrs[entry] + i;
+ ap = sat_extend(ap, i, 3, sizeof(Id), REPODATA_ATTRS_BLOCK);
+ if (entry < 0)
+ data->extraattrs[-1 - entry] = ap;
+ else
+ data->attrs[entry] = ap;
+ pp = ap + i;
*pp++ = keyid;
*pp++ = val;
*pp = 0;
*pp++ = keyid;
*pp++ = val;
*pp = 0;
int oldsize;
Id *ida, *pp;
int oldsize;
Id *ida, *pp;
- pp = 0;
- if (data->attrs && data->attrs[entry])
- for (pp = data->attrs[entry]; *pp; pp += 2)
+ if (entry < 0)
+ pp = data->extraattrs ? data->extraattrs[-1 - entry] : 0;
+ else
+ pp = data->attrs ? data->attrs[entry] : 0;
+ if (pp)
+ for (; *pp; pp += 2)
if (data->keys[*pp].name == keyname && data->keys[*pp].type == keytype)
break;
if (!pp || !*pp)
if (data->keys[*pp].name == keyname && data->keys[*pp].type == keytype)
break;
if (!pp || !*pp)
-Id repodata_globalize_id(Repodata *data, Id id)
+Id
+repodata_globalize_id(Repodata *data, Id id)
{
if (!data || !data->localpool)
return id;
{
if (!data || !data->localpool)
return id;
repodata_merge_attrs(Repodata *data, Id dest, Id src)
{
Id *keyp;
repodata_merge_attrs(Repodata *data, Id dest, Id src)
{
Id *keyp;
- if (dest == src || !(keyp = data->attrs[src]))
+ if (dest == src
+ || !(keyp = src < 0 ? data->extraattrs[-1 - src] : data->attrs[src]))
return;
for (; *keyp; keyp += 2)
repodata_insert_keyid(data, dest, keyp[0], keyp[1], 0);
return;
for (; *keyp; keyp += 2)
repodata_insert_keyid(data, dest, keyp[0], keyp[1], 0);
struct extdata newincore;
struct extdata newvincore;
struct extdata newincore;
struct extdata newvincore;
+ if (!data->attrs && !data->extraattrs)
return;
newvincore.buf = data->vincore;
return;
newvincore.buf = data->vincore;
addschema_prepare(data, schematacache);
memset(&newincore, 0, sizeof(newincore));
data_addid(&newincore, 0);
addschema_prepare(data, schematacache);
memset(&newincore, 0, sizeof(newincore));
data_addid(&newincore, 0);
- for (entry = 0; entry < nentry; entry++)
+ if (!data->attrs)
+ nentry = 0;
+ for (entry = data->extraattrs ? -data->nextra : 0; entry < nentry; entry++)
{
memset(seen, 0, data->nkeys * sizeof(Id));
sp = schema;
{
memset(seen, 0, data->nkeys * sizeof(Id));
sp = schema;
- dp = data->incoredata + data->incoreoffset[entry];
+ dp = entry2data(data, entry);
if (data->incoredata)
dp = data_read_id(dp, &oldschema);
else
if (data->incoredata)
dp = data_read_id(dp, &oldschema);
else
*sp++ = *keyp;
oldcount++;
}
*sp++ = *keyp;
oldcount++;
}
- if (data->attrs[entry])
- for (keyp = data->attrs[entry]; *keyp; keyp += 2)
+ keyp = entry < 0 ? data->extraattrs[-1 - entry] : data->attrs[entry];
+ if (keyp)
+ for (; *keyp; keyp += 2)
(oX being the old keyids (possibly overwritten), and nX being
the new keyids). This rules out sorting the keyids in order
to ensure a small schema count. */
(oX being the old keyids (possibly overwritten), and nX being
the new keyids). This rules out sorting the keyids in order
to ensure a small schema count. */
- data->incoreoffset[entry] = newincore.len;
+ if (entry < 0)
+ data->extraoffset[-1 - entry] = newincore.len;
+ else
+ data->incoreoffset[entry] = newincore.len;
data_addid(&newincore, schemaid);
for (keyp = data->schemadata + data->schemata[schemaid]; *keyp; keyp++)
{
data_addid(&newincore, schemaid);
for (keyp = data->schemadata + data->schemata[schemaid]; *keyp; keyp++)
{
- if (data->attrs[entry])
+ if (entry < 0 && data->extraattrs[-1 - entry])
+ sat_free(data->extraattrs[-1 - entry]);
+ else if (entry >= 0 && data->attrs[entry])
sat_free(data->attrs[entry]);
}
sat_free(schema);
sat_free(data->attrs[entry]);
}
sat_free(schema);
data->vincorelen = newvincore.len;
data->attrs = sat_free(data->attrs);
data->vincorelen = newvincore.len;
data->attrs = sat_free(data->attrs);
+ data->extraattrs = sat_free(data->extraattrs);
data->attrdata = sat_free(data->attrdata);
data->attriddata = sat_free(data->attriddata);
data->attrdatalen = 0;
data->attrdata = sat_free(data->attrdata);
data->attriddata = sat_free(data->attriddata);
data->attrdatalen = 0;
int start; /* start of solvables this repodata is valid for */
int end; /* last solvable + 1 of this repodata */
int start; /* start of solvables this repodata is valid for */
int end; /* last solvable + 1 of this repodata */
+ int extrastart;
+ int nextra;
FILE *fp; /* file pointer of solv file */
int error; /* corrupt solv file */
FILE *fp; /* file pointer of solv file */
int error; /* corrupt solv file */
unsigned int incoredatafree; /* free data len */
Id *incoreoffset; /* offset for all entries (ent2attr) */
unsigned int incoredatafree; /* free data len */
Id *incoreoffset; /* offset for all entries (ent2attr) */
+ Id *extraoffset; /* offset for all extra entries */
Id *verticaloffset; /* offset for all verticals, nkeys elements */
Id lastverticaloffset; /* end of verticals */
Id *verticaloffset; /* offset for all verticals, nkeys elements */
Id lastverticaloffset; /* end of verticals */
unsigned int vincorelen;
Id **attrs; /* un-internalized attributes */
unsigned int vincorelen;
Id **attrs; /* un-internalized attributes */
+ Id **extraattrs; /* Same, but for extra objects. */
unsigned char *attrdata; /* their string data space */
unsigned int attrdatalen;
Id *attriddata; /* their id space */
unsigned char *attrdata; /* their string data space */
unsigned int attrdatalen;
Id *attriddata; /* their id space */
/* management functions */
void repodata_init(Repodata *data, struct _Repo *repo, int localpool);
void repodata_extend(Repodata *data, Id p);
/* management functions */
void repodata_init(Repodata *data, struct _Repo *repo, int localpool);
void repodata_extend(Repodata *data, Id p);
+void repodata_extend_extra(Repodata *data, int nextra);
void repodata_extend_block(Repodata *data, Id p, int num);
void repodata_free(Repodata *data);
void repodata_extend_block(Repodata *data, Id p, int num);
void repodata_free(Repodata *data);
-dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
+dump_attr(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv)
- keyname = id2str(s->repo->pool, key->name);
+ keyname = id2str(repo->pool, key->name);
switch(key->type)
{
case REPOKEY_TYPE_ID:
if (data && data->localpool)
kv->str = stringpool_id2str(&data->spool, kv->id);
else
switch(key->type)
{
case REPOKEY_TYPE_ID:
if (data && data->localpool)
kv->str = stringpool_id2str(&data->spool, kv->id);
else
- kv->str = id2str(s->repo->pool, kv->id);
+ kv->str = id2str(repo->pool, kv->id);
printf("%s: %s\n", keyname, kv->str);
break;
case REPOKEY_TYPE_CONSTANTID:
printf("%s: %s\n", keyname, kv->str);
break;
case REPOKEY_TYPE_CONSTANTID:
- printf("%s: %s\n", keyname, dep2str(s->repo->pool, kv->id));
+ printf("%s: %s\n", keyname, dep2str(repo->pool, kv->id));
break;
case REPOKEY_TYPE_IDARRAY:
if (data && data->localpool)
printf("%s: %s\n", keyname, stringpool_id2str(&data->spool, kv->id));
else
break;
case REPOKEY_TYPE_IDARRAY:
if (data && data->localpool)
printf("%s: %s\n", keyname, stringpool_id2str(&data->spool, kv->id));
else
- printf("%s: %s\n", keyname, dep2str(s->repo->pool, kv->id));
+ printf("%s: %s\n", keyname, dep2str(repo->pool, kv->id));
break;
case REPOKEY_TYPE_STR:
printf("%s: %s\n", keyname, kv->str);
break;
case REPOKEY_TYPE_STR:
printf("%s: %s\n", keyname, kv->str);
+static int
+dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
+{
+ return dump_attr(s->repo, data, key, kv);
+}
+
/*
* dump all attributes for Id <p>
*/
/*
* dump all attributes for Id <p>
*/
Dataiterator di;
dataiterator_init(&di, repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE);
while (dataiterator_step(&di))
Dataiterator di;
dataiterator_init(&di, repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE);
while (dataiterator_step(&di))
- dump_repoattrs_cb(0, repo->pool->solvables + di.solvid, di.data, di.key,
- &di.kv);
+ dump_attr(repo, di.data, di.key, &di.kv);
printf("could not read repository\n");
printf("pool contains %d strings, %d rels, string size is %d\n", pool->ss.nstrings, pool->nrels, pool->ss.sstrings);
dump_repodata(repo);
printf("could not read repository\n");
printf("pool contains %d strings, %d rels, string size is %d\n", pool->ss.nstrings, pool->nrels, pool->ss.sstrings);
dump_repodata(repo);
- printf("repo contains %d solvables\n", repo->nsolvables);
+ printf("repo contains %d solvables %d non-solvables\n", repo->nsolvables, repo->nextra);
for (i = repo->start, n = 1; i < repo->end; i++)
{
s = pool->solvables + i;
for (i = repo->start, n = 1; i < repo->end; i++)
{
s = pool->solvables + i;
+ for (i = 0; i < repo->nextra; i++)
+ {
+ printf("\nextra %d:\n", i);
+ Dataiterator di;
+ dataiterator_init(&di, repo, -1 - i, 0, 0, SEARCH_EXTRA | SEARCH_NO_STORAGE_SOLVABLE);
+ while (dataiterator_step(&di))
+ dump_attr(repo, di.data, di.key, &di.kv);
+ }
#if 0
tryme(repo, 0, SOLVABLE_MEDIANR, 0, 0);
printf("\n");
#if 0
tryme(repo, 0, SOLVABLE_MEDIANR, 0, 0);
printf("\n");
char *sp[5];
struct parsedata pd;
Repodata *data = 0;
char *sp[5];
struct parsedata pd;
Repodata *data = 0;
if ((flags & SUSETAGS_EXTEND) && repo->nrepodata)
indesc = 1;
if ((flags & SUSETAGS_EXTEND) && repo->nrepodata)
indesc = 1;
+ /* XXX deactivate test code */
+ blanr = 0;
/*
* read complete file
*
/*
* read complete file
*
continue;
case CTAG('=', 'I', 'n', 's'):
repodata_set_str(data, last_found_pack, langtag(&pd, SOLVABLE_MESSAGEINS, language), line + 6);
continue;
case CTAG('=', 'I', 'n', 's'):
repodata_set_str(data, last_found_pack, langtag(&pd, SOLVABLE_MESSAGEINS, language), line + 6);
+ if (blanr)
+ {
+ /* XXX testcode */
+ repo_set_str(repo, blanr, SOLVABLE_MESSAGEINS, line + 6);
+ blanr--;
+ }
continue;
case CTAG('=', 'D', 'e', 'l'):
repodata_set_str(data, last_found_pack, langtag(&pd, SOLVABLE_MESSAGEDEL, language), line + 6);
continue;
case CTAG('=', 'D', 'e', 'l'):
repodata_set_str(data, last_found_pack, langtag(&pd, SOLVABLE_MESSAGEDEL, language), line + 6);
case CTAG('=', 'C', 'k', 's'):
set_checksum(data, last_found_pack, SOLVABLE_CHECKSUM, line + 6);
break;
case CTAG('=', 'C', 'k', 's'):
set_checksum(data, last_found_pack, SOLVABLE_CHECKSUM, line + 6);
break;
+ case CTAG('=', 'L', 'a', 'n'):
+ language = strdup(line + 6);
+ break;
case CTAG('=', 'P', 'a', 't'):
case CTAG('=', 'P', 'k', 'g'):
case CTAG('=', 'P', 'a', 't'):
case CTAG('=', 'P', 'k', 'g'):
Id schematacache[256];
Id *solvschemata;
Id schematacache[256];
Id *solvschemata;
-repo_write_cb_needed(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
+repo_write_collect_needed(struct cbdata *cbdata, Repo *repo, Repodata *data, Repokey *key, KeyValue *kv)
- struct cbdata *cbdata = vcbdata;
- Repo *repo = s ? s->repo : 0;
-#if 0
- fprintf(stderr, "solvable %d (%s): key (%d)%s %d\n", s ? s - s->repo->pool->solvables : 0, s ? id2str(s->repo->pool, s->name) : "", key->name, id2str(repo->pool, key->name), key->type);
-#endif
rm = cbdata->keymap[cbdata->keymapstart[data - data->repo->repodata] + (key - data->keys)];
if (!rm)
return SEARCH_NEXT_KEY; /* we do not want this one */
rm = cbdata->keymap[cbdata->keymapstart[data - data->repo->repodata] + (key - data->keys)];
if (!rm)
return SEARCH_NEXT_KEY; /* we do not want this one */
-repo_write_cb_adddata(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
+repo_write_cb_needed(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
{
struct cbdata *cbdata = vcbdata;
{
struct cbdata *cbdata = vcbdata;
+ Repo *repo = s ? s->repo : 0;
+#if 0
+ fprintf(stderr, "solvable %d (%s): key (%d)%s %d\n", s ? s - s->repo->pool->solvables : 0, s ? id2str(s->repo->pool, s->name) : "", key->name, id2str(repo->pool, key->name), key->type);
+#endif
+ return repo_write_collect_needed(cbdata, repo, data, key, kv);
+}
+
+static int
+repo_write_adddata(struct cbdata *cbdata, Repodata *data, Repokey *key, KeyValue *kv)
+{
int rm;
Id id;
unsigned int u32;
int rm;
Id id;
unsigned int u32;
+repo_write_cb_adddata(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
+{
+ struct cbdata *cbdata = vcbdata;
+ return repo_write_adddata(cbdata, data, key, kv);
+}
+
+static int
traverse_dirs(Dirpool *dp, Id *dirmap, Id n, Id dir, Id *used)
{
Id sib, child;
traverse_dirs(Dirpool *dp, Id *dirmap, Id n, Id dir, Id *used)
{
Id sib, child;
cbdata.schema = sat_calloc(cbdata.nmykeys, sizeof(Id));
cbdata.sp = cbdata.schema;
cbdata.solvschemata = sat_calloc(repo->nsolvables, sizeof(Id));
cbdata.schema = sat_calloc(cbdata.nmykeys, sizeof(Id));
cbdata.sp = cbdata.schema;
cbdata.solvschemata = sat_calloc(repo->nsolvables, sizeof(Id));
+ cbdata.extraschemata = sat_calloc(repo->nextra, sizeof(Id));
idarraydata = repo->idarraydata;
idarraydata = repo->idarraydata;
cbdata.solvschemata[n] = addschema(&cbdata, cbdata.schema);
n++;
}
cbdata.solvschemata[n] = addschema(&cbdata, cbdata.schema);
n++;
}
+ if (repo->nextra && anyrepodataused)
+ for (i = -1; i >= -repo->nextra; i--)
+ {
+ Dataiterator di;
+ dataiterator_init(&di, repo, i, 0, 0, SEARCH_EXTRA | SEARCH_NO_STORAGE_SOLVABLE);
+ cbdata.sp = cbdata.schema;
+ while (dataiterator_step(&di))
+ repo_write_collect_needed(&cbdata, repo, di.data, di.key, &di.kv);
+ *cbdata.sp = 0;
+ cbdata.extraschemata[-1 - i] = addschema(&cbdata, cbdata.schema);
+ }
/* If we have fileinfos to write, setup schemas and increment needid[]
of the right strings. */
/* If we have fileinfos to write, setup schemas and increment needid[]
of the right strings. */
+ if (repo->nextra && anyrepodataused)
+ for (i = -1; i >= -repo->nextra; i--)
+ {
+ Dataiterator di;
+ dataiterator_init(&di, repo, i, 0, 0, SEARCH_EXTRA | SEARCH_NO_STORAGE_SOLVABLE);
+ entrysize = xd->len;
+ data_addid(xd, cbdata.extraschemata[-1 - i]);
+ cbdata.vstart = -1;
+ while (dataiterator_step(&di))
+ repo_write_adddata(&cbdata, di.data, di.key, &di.kv);
+ entrysize = xd->len - entrysize;
+ if (entrysize > maxentrysize)
+ maxentrysize = entrysize;
+ }
+
/********************************************************************/
/* write header */
/* write file header */
write_u32(fp, 'S' << 24 | 'O' << 16 | 'L' << 8 | 'V');
/********************************************************************/
/* write header */
/* write file header */
write_u32(fp, 'S' << 24 | 'O' << 16 | 'L' << 8 | 'V');
- write_u32(fp, SOLV_VERSION_6);
+ write_u32(fp, repo->nextra ? SOLV_VERSION_7 : SOLV_VERSION_6);
+
/* write counts */
write_u32(fp, nstrings);
/* write counts */
write_u32(fp, nstrings);
write_u32(fp, cbdata.nmykeys);
write_u32(fp, cbdata.nmyschemata);
write_u32(fp, nsubfiles); /* info blocks. */
write_u32(fp, cbdata.nmykeys);
write_u32(fp, cbdata.nmyschemata);
write_u32(fp, nsubfiles); /* info blocks. */
+ if (repo->nextra)
+ write_u32(fp, repo->nextra);
solv_flags = 0;
solv_flags |= SOLV_FLAG_PREFIX_POOL;
write_u32(fp, solv_flags);
solv_flags = 0;
solv_flags |= SOLV_FLAG_PREFIX_POOL;
write_u32(fp, solv_flags);
/*
* write Solvable data
*/
/*
* write Solvable data
*/
+ if (repo->nsolvables || repo->nextra)
{
write_id(fp, maxentrysize);
write_id(fp, cbdata.extdata[0].len);
{
write_id(fp, maxentrysize);
write_id(fp, cbdata.extdata[0].len);
- write_compressed_page(fp, vpage, lpage);
+ write_compressed_page(fp, vpage, lpage);
sat_free(cbdata.owndirpool->dirtraverse);
}
sat_free(needid);
sat_free(cbdata.owndirpool->dirtraverse);
}
sat_free(needid);
+ sat_free(cbdata.extraschemata);
sat_free(cbdata.solvschemata);
sat_free(cbdata.myschemadata);
sat_free(cbdata.myschemata);
sat_free(cbdata.solvschemata);
sat_free(cbdata.myschemadata);
sat_free(cbdata.myschemata);