summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pooltypes.h1
-rw-r--r--src/repo.c55
-rw-r--r--src/repo.h2
-rw-r--r--src/repo_solv.c47
-rw-r--r--src/repodata.c147
-rw-r--r--src/repodata.h5
-rw-r--r--tools/dumpsolv.c29
-rw-r--r--tools/repo_susetags.c12
-rw-r--r--tools/repo_write.c64
9 files changed, 298 insertions, 64 deletions
diff --git a/src/pooltypes.h b/src/pooltypes.h
index cfe837d..836bc9b 100644
--- a/src/pooltypes.h
+++ b/src/pooltypes.h
@@ -21,6 +21,7 @@
#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
diff --git a/src/repo.c b/src/repo.c
index e147cfb..fc7229b 100644
--- a/src/repo.c
+++ b/src/repo.c
@@ -595,8 +595,8 @@ repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md)
KeyValue kv;
Pool *pool = repo->pool;
Repodata *data;
- Solvable *s;
int i, j, flags;
+ Solvable *s;
md->stop = 0;
if (!p)
@@ -610,10 +610,14 @@ repo_search_md(Repo *repo, Id p, Id keyname, struct matchdata *md)
}
return;
}
- 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))
{
+ s = pool->solvables + p;
switch(keyname)
{
case 0:
@@ -868,8 +872,26 @@ repo_findrepodata(Repo *repo, Id p, Id keyname)
/* 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;
return data;
+ }
for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
if (p == data->end)
break;
@@ -885,28 +907,45 @@ void
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);
- 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);
- 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);
- 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);
}
void
@@ -916,7 +955,7 @@ repo_internalize(Repo *repo)
Repodata *data;
for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
- if (data->attrs)
+ if (data->attrs || data->extraattrs)
repodata_internalize(data);
}
diff --git a/src/repo.h b/src/repo.h
index 2661835..07dc687 100644
--- a/src/repo.h
+++ b/src/repo.h
@@ -40,6 +40,7 @@ typedef struct _Repo {
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 */
@@ -155,6 +156,7 @@ typedef struct _KeyValue {
#define SEARCH_NOCASE (1<<8)
#define SEARCH_NO_STORAGE_SOLVABLE (1<<9)
+#define SEARCH_EXTRA (1<<10)
/* Internal */
#define __SEARCH_ONESOLVABLE (1 << 31)
diff --git a/src/repo_solv.c b/src/repo_solv.c
index 9ede7d3..119a0db 100644
--- a/src/repo_solv.c
+++ b/src/repo_solv.c
@@ -722,7 +722,7 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
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 */
@@ -772,6 +772,8 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
{
case SOLV_VERSION_6:
break;
+ case SOLV_VERSION_7:
+ break;
default:
pool_debug(pool, SAT_ERROR, "unsupported SOLV version\n");
return SOLV_ERROR_UNSUPPORTED;
@@ -786,6 +788,10 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
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)
@@ -806,6 +812,11 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
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");
@@ -1225,7 +1236,7 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
size_idarray += keys[i].size;
}
- if (numsolv)
+ if (numsolv || numextra)
{
maxsize = read_id(&data, 0);
allsize = read_id(&data, 0);
@@ -1267,6 +1278,18 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
else
s = 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 */
@@ -1277,7 +1300,7 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
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)
@@ -1308,9 +1331,20 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
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);
}
+ 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)
{
@@ -1319,7 +1353,10 @@ repo_add_solv_parent(Repo *repo, FILE *fp, Repodata *parent)
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)
{
diff --git a/src/repodata.c b/src/repodata.c
index ddcc767..ea4b399 100644
--- a/src/repodata.c
+++ b/src/repodata.c
@@ -54,7 +54,10 @@ repodata_init(Repodata *data, Repo *repo, int localpool)
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->extraoffset = sat_extend_resize(0, repo->nextra, sizeof(Id), REPODATA_BLOCK);
data->pagefd = -1;
}
@@ -74,6 +77,7 @@ repodata_free(Repodata *data)
sat_free(data->incoredata);
sat_free(data->incoreoffset);
+ sat_free(data->extraoffset);
sat_free(data->verticaloffset);
sat_free(data->blob_store);
@@ -83,6 +87,7 @@ repodata_free(Repodata *data)
sat_free(data->vincore);
sat_free(data->attrs);
+ sat_free(data->extraattrs);
sat_free(data->attrdata);
sat_free(data->attriddata);
@@ -363,6 +368,15 @@ maybe_load_repodata(Repodata *data, Id *keyid)
return 0;
}
+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)
{
@@ -373,7 +387,7 @@ repodata_lookup_id(Repodata *data, Id entry, Id keyid)
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++)
@@ -403,7 +417,7 @@ repodata_lookup_str(Repodata *data, Id entry, Id keyid)
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++)
@@ -441,7 +455,7 @@ repodata_lookup_num(Repodata *data, Id entry, Id keyid, unsigned int *value)
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++)
@@ -471,7 +485,7 @@ repodata_lookup_void(Repodata *data, Id entry, Id keyid)
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)
@@ -489,7 +503,7 @@ repodata_lookup_bin_checksum(Repodata *data, Id entry, Id keyid, Id *typep)
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)
@@ -511,10 +525,11 @@ repodata_search(Repodata *data, Id entry, Id keyname, int (*callback)(void *cbda
int stop;
KeyValue kv;
- if (!maybe_load_repodata(data, 0))
+ if (entry < 0
+ || !maybe_load_repodata(data, 0))
return;
- dp = data->incoredata + data->incoreoffset[entry];
+ dp = entry2data(data, entry);
dp = data_read_id(dp, &schema);
keyp = data->schemadata + data->schemata[schema];
if (keyname)
@@ -577,7 +592,11 @@ dataiterator_newdata(Dataiterator *di)
return;
Id schema;
- 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)
@@ -626,6 +645,11 @@ dataiterator_init(Dataiterator *di, Repo *repo, Id p, Id keyname,
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;
}
@@ -843,20 +867,37 @@ restart:
{
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;
- 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;
}
- 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)
@@ -917,6 +958,21 @@ repodata_extend(Repodata *data, Id p)
}
void
+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)
@@ -943,16 +999,23 @@ static void
repodata_insert_keyid(Repodata *data, Id entry, Id keyid, Id val, int overwrite)
{
Id *pp;
+ Id *ap;
int i;
- if (!data->attrs)
+ if (!data->attrs && entry >= 0)
{
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];
i = 0;
- if (data->attrs[entry])
+ if (ap)
{
- 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)
@@ -966,10 +1029,14 @@ repodata_insert_keyid(Repodata *data, Id entry, Id keyid, Id val, int overwrite)
}
return;
}
- i = pp - data->attrs[entry];
+ i = pp - ap;
}
- 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;
@@ -1096,9 +1163,12 @@ repoadata_add_array(Repodata *data, Id entry, Id keyname, Id keytype, int entrys
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)
@@ -1231,7 +1301,8 @@ repodata_chk2str(Repodata *data, Id type, const unsigned char *buf)
return str;
}
-Id repodata_globalize_id(Repodata *data, Id id)
+Id
+repodata_globalize_id(Repodata *data, Id id)
{
if (!data || !data->localpool)
return id;
@@ -1300,7 +1371,8 @@ void
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);
@@ -1425,7 +1497,7 @@ repodata_internalize(Repodata *data)
struct extdata newincore;
struct extdata newvincore;
- if (!data->attrs)
+ if (!data->attrs && !data->extraattrs)
return;
newvincore.buf = data->vincore;
@@ -1440,11 +1512,13 @@ repodata_internalize(Repodata *data)
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;
- dp = data->incoredata + data->incoreoffset[entry];
+ dp = entry2data(data, entry);
if (data->incoredata)
dp = data_read_id(dp, &oldschema);
else
@@ -1468,8 +1542,9 @@ fprintf(stderr, "schemadata %p\n", data->schemadata);
*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)
{
if (!seen[*keyp])
{
@@ -1497,7 +1572,10 @@ fprintf(stderr, "schemadata %p\n", data->schemadata);
(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++)
{
@@ -1591,7 +1669,9 @@ fprintf(stderr, "schemadata %p\n", data->schemadata);
}
dp = ndp;
}
- 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);
@@ -1607,6 +1687,7 @@ fprintf(stderr, "schemadata %p\n", data->schemadata);
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;
diff --git a/src/repodata.h b/src/repodata.h
index 6139db9..091390c 100644
--- a/src/repodata.h
+++ b/src/repodata.h
@@ -57,6 +57,8 @@ typedef struct _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 */
@@ -81,6 +83,7 @@ typedef struct _Repodata {
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 */
@@ -100,6 +103,7 @@ typedef struct _Repodata {
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 */
@@ -111,6 +115,7 @@ typedef struct _Repodata {
/* 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);
diff --git a/tools/dumpsolv.c b/tools/dumpsolv.c
index 0c9816a..a6f5fe4 100644
--- a/tools/dumpsolv.c
+++ b/tools/dumpsolv.c
@@ -58,28 +58,28 @@ printids(Repo *repo, char *kind, Offset ido)
}
int
-dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
+dump_attr(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv)
{
const char *keyname;
- 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
- 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, 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
- 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);
@@ -110,6 +110,12 @@ dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyV
return 0;
}
+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>
*/
@@ -123,8 +129,7 @@ dump_repoattrs(Repo *repo, Id p)
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);
#endif
}
@@ -244,7 +249,7 @@ int main(int argc, char **argv)
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;
@@ -276,6 +281,14 @@ int main(int argc, char **argv)
#endif
n++;
}
+ 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");
diff --git a/tools/repo_susetags.c b/tools/repo_susetags.c
index 7443fdf..e9fd823 100644
--- a/tools/repo_susetags.c
+++ b/tools/repo_susetags.c
@@ -457,6 +457,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, const char *language, int fla
char *sp[5];
struct parsedata pd;
Repodata *data = 0;
+ Id blanr = -1;
if ((flags & SUSETAGS_EXTEND) && repo->nrepodata)
indesc = 1;
@@ -477,6 +478,8 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, const char *language, int fla
linep = line;
s = 0;
+ /* XXX deactivate test code */
+ blanr = 0;
/*
* read complete file
*
@@ -800,6 +803,12 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, const char *language, int fla
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);
@@ -850,6 +859,9 @@ repo_add_susetags(Repo *repo, FILE *fp, Id vendor, const char *language, int fla
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'):
diff --git a/tools/repo_write.c b/tools/repo_write.c
index 42e2352..81e2e3a 100644
--- a/tools/repo_write.c
+++ b/tools/repo_write.c
@@ -381,6 +381,7 @@ struct cbdata {
Id schematacache[256];
Id *solvschemata;
+ Id *extraschemata;
struct extdata *extdata;
@@ -624,16 +625,11 @@ setdirused(struct cbdata *cbdata, Dirpool *dp, Id dir)
}
static int
-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;
Id id;
int rm;
-#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 */
@@ -665,9 +661,19 @@ repo_write_cb_needed(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, K
}
static int
-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;
+ 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;
@@ -765,6 +771,13 @@ repo_write_cb_adddata(void *vcbdata, Solvable *s, Repodata *data, Repokey *key,
}
static int
+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;
@@ -1137,6 +1150,7 @@ for (i = 1; i < cbdata.nmykeys; i++)
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;
@@ -1235,6 +1249,17 @@ for (i = 1; i < cbdata.nmykeys; i++)
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. */
@@ -1478,13 +1503,29 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
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);
+ 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_u32(fp, SOLV_VERSION_6);
+ write_u32(fp, repo->nextra ? SOLV_VERSION_7 : SOLV_VERSION_6);
+
/* write counts */
write_u32(fp, nstrings);
@@ -1494,6 +1535,8 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
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);
@@ -1644,7 +1687,7 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
/*
* write Solvable data
*/
- if (repo->nsolvables)
+ if (repo->nsolvables || repo->nextra)
{
write_id(fp, maxentrysize);
write_id(fp, cbdata.extdata[0].len);
@@ -1685,7 +1728,7 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
}
}
if (lpage)
- write_compressed_page(fp, vpage, lpage);
+ write_compressed_page(fp, vpage, lpage);
}
#if 0
@@ -1721,6 +1764,7 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
sat_free(cbdata.owndirpool->dirtraverse);
}
sat_free(needid);
+ sat_free(cbdata.extraschemata);
sat_free(cbdata.solvschemata);
sat_free(cbdata.myschemadata);
sat_free(cbdata.myschemata);