#include "util.h"
#include "evr.h"
+#define SOLVABLE_BLOCK 255
// reset all whatprovides
//
pool->nrels = 1;
// pre-alloc space for a Solvable
- pool->solvables = (Solvable *)xcalloc(2, sizeof(Solvable));
+ pool->solvables = (Solvable *)xcalloc(SOLVABLE_BLOCK + 1, sizeof(Solvable));
pool->nsolvables = 2;
queue_init(&pool->vendormap);
s = pool->solvables + SYSTEMSOLVABLE;
xfree(pool);
}
+Id
+pool_add_solvable(Pool *pool)
+{
+ if ((pool->nsolvables & SOLVABLE_BLOCK) == 0)
+ pool->solvables = xrealloc2(pool->solvables, pool->nsolvables + (SOLVABLE_BLOCK + 1), sizeof(Solvable));
+ memset(pool->solvables + pool->nsolvables, 0, sizeof(Solvable));
+ return pool->nsolvables++;
+}
+
+Id
+pool_add_solvable_block(Pool *pool, int count)
+{
+ Id nsolvables = pool->nsolvables;
+ if (!count)
+ return nsolvables;
+ if (((nsolvables - 1) | SOLVABLE_BLOCK) != ((nsolvables + count - 1) | SOLVABLE_BLOCK))
+ pool->solvables = xrealloc2(pool->solvables, (nsolvables + count + SOLVABLE_BLOCK) & ~SOLVABLE_BLOCK, sizeof(Solvable));
+ memset(pool->solvables + nsolvables, 0, sizeof(Solvable) * count);
+ pool->nsolvables += count;
+ return nsolvables;
+}
+
+void
+pool_free_solvable_block(Pool *pool, Id start, int count, int reuseids)
+{
+ if (!count)
+ return;
+ if (reuseids && start + count == pool->nsolvables)
+ {
+ /* might want to shrink solvable array */
+ pool->nsolvables = start;
+ return;
+ }
+ memset(pool->solvables + start, 0, sizeof(Solvable) * count);
+}
static Pool *pool_shrink_whatprovides_sortcmp_data;
* Delete a pool
*/
extern void pool_free(Pool *pool);
+
+extern Id pool_add_solvable(Pool *pool);
+extern Id pool_add_solvable_block(Pool *pool, int count);
+
+extern void pool_free_solvable_block(Pool *pool, Id start, int count, int reuseids);
+
/**
* Prepares a pool for solving
*/
pool_freewhatprovides(pool);
for (i = 0; i < pool->nrepos; i++)
repo_freedata(pool->repos[i]);
- /* the first two solvables don't belong to a repo */
- if (pool->nsolvables > 2 && !reuseids)
- memset(pool->solvables + 2, 0, (pool->nsolvables - 2) * sizeof(Solvable));
pool->repos = xfree(pool->repos);
pool->nrepos = 0;
- if (reuseids)
- pool->nsolvables = 2;
+ /* the first two solvables don't belong to a repo */
+ pool_free_solvable_block(pool, 2, pool->nsolvables - 2, reuseids);
}
Offset
return repo->name;
}
+static inline Id repo_add_solvable(Repo *repo)
+{
+ extern Id pool_add_solvable(Pool *pool);
+ Id p = pool_add_solvable(repo->pool);
+ if (!repo->start || repo->start == repo->end)
+ {
+ repo->start = p;
+ repo->end = p + 1;
+ return p;
+ }
+ if (p < repo->start)
+ repo->start = p;
+ if (p + 1 > repo->end)
+ repo->end = p + 1;
+ return p;
+}
+
+static inline Id repo_add_solvable_block(Repo *repo, int count)
+{
+ extern Id pool_add_solvable_block(Pool *pool, int count);
+ Id p;
+ if (!count)
+ return 0;
+ p = pool_add_solvable_block(repo->pool, count);
+ if (!repo->start || repo->start == repo->end)
+ {
+ repo->start = p;
+ repo->end = p + count;
+ return p;
+ }
+ if (p < repo->start)
+ repo->start = p;
+ if (p + count > repo->end)
+ repo->end = p + count;
+ return p;
+}
+
+/* does not modify repo->nsolvables! */
+static inline void repo_free_solvable_block(Repo *repo, Id start, int count, int reuseids)
+{
+ extern void pool_free_solvable_block(Pool *pool, Id start, int count, int reuseids);
+ if (start + count == repo->end)
+ repo->end -= count;
+ pool_free_solvable_block(repo->pool, start, count, reuseids);
+}
+
#endif /* REPO_H */
idarraydataend = 0;
}
-
- /* alloc space for our solvables */
- if (numsolv) /* clear newly allocated area */
- {
- pool->solvables = (Solvable *)xrealloc(pool->solvables, (pool->nsolvables + numsolv) * sizeof(Solvable));
-
- memset(pool->solvables + pool->nsolvables, 0, numsolv * sizeof(Solvable));
- if (!repo->start || repo->start == repo->end)
- repo->start = pool->nsolvables;
- repo->end = pool->nsolvables;
- }
-
/*
* read solvables
*/
#if 0
printf("read solvables\n");
#endif
- for (i = 0, s = pool->solvables + pool->nsolvables; i < numsolv; i++, s++)
+ id = repo_add_solvable_block(repo, numsolv);
+ s = pool->solvables + id;
+ for (i = 0; i < numsolv; i++, s++)
{
s->repo = repo;
databits = 0;
}
}
}
+ repo->nsolvables += numsolv;
xfree(idmap);
xfree(solvdata);
-
- repo->end += numsolv;
- repo->nsolvables += numsolv;
- pool->nsolvables += numsolv;
}
// EOF
#include "util.h"
#include "repo_content.h"
-#define PACK_BLOCK 16
-
static int
split(char *l, char **sp, int m)
{
char *line, *linep;
int aline;
Solvable *s;
- int pack;
+ Id id;
struct parsedata pd;
memset(&pd, 0, sizeof(pd));
pd.repo = repo;
linep = line;
- pack = 0;
s = 0;
- if (!repo->start || repo->start == repo->end)
- repo->start = pool->nsolvables;
- repo->end = pool->nsolvables;
-
for (;;)
{
char *fields[2];
#define istag(x) !strcmp (key, x)
if (istag ("PRODUCT"))
{
+ /* finish old solvable */
if (s && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
if (s)
s->supplements = repo_fix_legacy(repo, s->provides, s->supplements);
/* Only support one product. */
pd.kind = "product";
- if ((pack & PACK_BLOCK) == 0)
- {
- pool->solvables = realloc(pool->solvables, (pool->nsolvables + pack + PACK_BLOCK + 1) * sizeof(Solvable));
- memset(pool->solvables + pool->nsolvables + pack, 0, (PACK_BLOCK + 1) * sizeof(Solvable));
- }
- s = pool->solvables + pool->nsolvables + pack;
+ id = repo_add_solvable(repo);
+ s = pool->solvables + id;
s->repo = repo;
+ repo->nsolvables++;
s->name = str2id(pool, join(&pd, pd.kind, ":", value), 1);
- pack++;
}
else if (istag ("VERSION"))
/* without a release? but that's like zypp implements it */
if (s)
s->supplements = repo_fix_legacy(repo, s->provides, s->supplements);
- pool->nsolvables += pack;
- repo->nsolvables += pack;
- repo->end += pack;
if (pd.tmp)
free(pd.tmp);
free(line);
NUMSTATES
};
-#define PACK_BLOCK 255
-
struct stateswitch {
enum state from;
char *ename;
int docontent; // handle content
// repo data
- int pack; // number of solvables
-
Pool *pool; // current pool
- Repo *repo; // current repo
- Solvable *start; // collected solvables
+ Repo *repo; // current repo
+ Solvable *solvable; // current solvable
// package data
int epoch; // epoch (as offset into evrspace)
Parsedata *pd = (Parsedata *)userData;
struct stateswitch *sw;
Pool *pool = pd->pool;
- Solvable *s = pd->start ? pd->start + pd->pack : 0;
+ Solvable *s = pd->solvable;
+ Id id;
if (pd->depth != pd->statedepth)
{
}
break;
- case STATE_SUBCHANNEL:
- pd->pack = 0;
- break;
-
-
case STATE_PACKAGE: /* solvable name */
-
- if ((pd->pack & PACK_BLOCK) == 0) /* alloc new block ? */
- {
- pool->solvables = (Solvable *)realloc(pool->solvables, (pool->nsolvables + pd->pack + PACK_BLOCK + 1) * sizeof(Solvable));
- pd->start = pool->solvables + pool->nsolvables;
- memset(pd->start + pd->pack, 0, (PACK_BLOCK + 1) * sizeof(Solvable));
- }
-
+ id = repo_add_solvable(pd->repo);
+ pd->solvable = pool->solvables + id;
if (!strcmp(name, "selection"))
pd->kind = "selection";
else if (!strcmp(name, "pattern"))
pd->version = 0;
pd->release = 0;
#if 0
- fprintf(stderr, "package #%d\n", pd->pack);
+ fprintf(stderr, "package #%d\n", id);
#endif
break;
}
}
- //fprintf(stderr, "pack %d\n", pd->pack);
- //fprintf(stderr, "repo %d\n", s->requires);
-
if (!s->requires)
return 0;
{
Parsedata *pd = (Parsedata *)userData;
Pool *pool = pd->pool;
- Solvable *s = pd->start ? pd->start + pd->pack : NULL;
+ Solvable *s = pd->solvable;
Id evr;
if (pd->depth != pd->statedepth)
case STATE_PACKAGE: /* package complete */
s->repo = pd->repo;
+ pd->repo->nsolvables++;
if (!s->arch) /* default to "noarch" */
s->arch = ARCH_NOARCH;
#endif
free(cflavor);
}
-
- pd->pack++; /* inc pack count */
-
break;
case STATE_NAME:
s->name = str2id(pool, pd->content, 1);
int i, l;
struct stateswitch *sw;
- if (repo->start && repo->start + repo->nsolvables != pool->nsolvables)
- abort();
- if (!repo->start || repo->start == repo->end)
- repo->start = pool->nsolvables;
- repo->end = pool->nsolvables;
-
/* prepare parsedata */
memset(&pd, 0, sizeof(pd));
for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
}
XML_ParserFree(parser);
- // adapt package count
- pool->nsolvables += pd.pack;
- repo->nsolvables += pd.pack;
- repo->end += pd.pack;
-
free(pd.content);
free(pd.evrspace);
}
NUMSTATES
};
-#define PACK_BLOCK 255
-
struct stateswitch {
enum state from;
int lcontent;
int acontent;
int docontent;
- int pack;
Pool *pool;
Repo *repo;
- Solvable *start;
+ Solvable *solvable;
char *kind;
struct stateswitch *swtab[NUMSTATES];
{
struct parsedata *pd = userData;
Pool *pool = pd->pool;
- Solvable *s = pd->start ? pd->start + pd->pack : 0;
+ Solvable *s = pd->solvable;
struct stateswitch *sw;
+ Id id;
if (pd->depth != pd->statedepth)
{
if (pd->kind && !strcmp(pd->kind, "patch"))
{
s->repo = pd->repo;
+ pd->repo->nsolvables++;
if (!s->arch)
s->arch = ARCH_NOARCH;
s->provides = repo_addid_dep(pd->repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
- pd->pack++;
}
pd->kind = "atom";
pd->state = STATE_PATCH;
}
else
pd->kind = "patch";
- if ((pd->pack & PACK_BLOCK) == 0)
- {
- pool->solvables = realloc(pool->solvables, (pool->nsolvables + pd->pack + PACK_BLOCK + 1) * sizeof(Solvable));
- pd->start = pool->solvables + pool->nsolvables;
- memset(pd->start + pd->pack, 0, (PACK_BLOCK + 1) * sizeof(Solvable));
- }
+ id = repo_add_solvable(pd->repo);
+ pd->solvable = pool->solvables + id;
#if 0
- fprintf(stderr, "package #%d\n", pd->pack);
+ fprintf(stderr, "package #%d\n", id);
#endif
break;
case STATE_VERSION:
{
struct parsedata *pd = userData;
Pool *pool = pd->pool;
- Solvable *s = pd->start ? pd->start + pd->pack : 0;
+ Solvable *s = pd->solvable;
if (pd->depth != pd->statedepth)
{
if (!strcmp(name, "patch") && strcmp(pd->kind, "patch"))
break; /* already closed */
s->repo = pd->repo;
+ pd->repo->nsolvables++;
if (!s->arch)
s->arch = ARCH_NOARCH;
if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
s->provides = repo_addid_dep(pd->repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
s->supplements = repo_fix_legacy(pd->repo, s->provides, s->supplements);
- pd->pack++;
break;
case STATE_NAME:
s->name = str2id(pool, pd->content, 1);
int i, l;
struct stateswitch *sw;
- if (repo->start && repo->start + repo->nsolvables != pool->nsolvables)
- abort();
- if (!repo->start || repo->start == repo->end)
- repo->start = pool->nsolvables;
- repo->end = pool->nsolvables;
-
memset(&pd, 0, sizeof(pd));
for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
{
}
XML_ParserFree(parser);
- pool->nsolvables += pd.pack;
- repo->nsolvables += pd.pack;
- repo->end += pd.pack;
-
free(pd.content);
}
unsigned int refmask, h;
int asolv;
- if (repo->start && repo->start + repo->nsolvables != pool->nsolvables)
- abort();
- if (!repo->start || repo->start == repo->end)
- repo->start = pool->nsolvables;
- repo->end = pool->nsolvables;
if (repo->start != repo->end)
abort(); /* FIXME: rpmdbid */
exit(1);
}
dbidp = (unsigned char *)&dbid;
- pool->solvables = xrealloc(pool->solvables, (pool->nsolvables + 256) * sizeof(Solvable));
- memset(pool->solvables + pool->nsolvables, 0, 256 * sizeof(Solvable));
repo->rpmdbid = xcalloc(256, sizeof(unsigned int));
asolv = 256;
rpmheadsize = 0;
rpmhead = 0;
i = 0;
+ s = 0;
while (dbc->c_get(dbc, &key, &data, DB_NEXT) == 0)
{
+ if (!s)
+ {
+ id = repo_add_solvable(repo);
+ s = pool->solvables + id;
+ }
if (i >= asolv)
{
- pool->solvables = xrealloc(pool->solvables, (pool->nsolvables + asolv + 256) * sizeof(Solvable));
- memset(pool->solvables + pool->nsolvables + asolv, 0, 256 * sizeof(Solvable));
repo->rpmdbid = xrealloc(repo->rpmdbid, (asolv + 256) * sizeof(unsigned int));
memset(repo->rpmdbid + asolv, 0, 256 * sizeof(unsigned int));
asolv += 256;
}
- pool->solvables[pool->nsolvables + i].repo = repo;
if (key.size != 4)
{
fprintf(stderr, "corrupt Packages database (key size)\n");
memcpy(rpmhead->data, (unsigned char *)data.data + 8, rpmhead->cnt * 16 + rpmhead->dcnt);
rpmhead->dp = rpmhead->data + rpmhead->cnt * 16;
repo->rpmdbid[i] = dbid;
- if (rpm2solv(pool, repo, pool->solvables + pool->nsolvables + i, rpmhead))
- i++;
+ if (rpm2solv(pool, repo, s, rpmhead))
+ {
+ s->repo = repo;
+ repo->nsolvables++;
+ i++;
+ s = 0;
+ }
+ else
+ {
+ memset(s, 0, sizeof(*s)); /* oops, reuse that one */
+ }
+ }
+ if (s)
+ {
+ /* oops, could not reuse. free it instead */
+ repo_free_solvable_block(repo, s - pool->solvables, 1, 1);
+ s = 0;
}
- nrpmids = i;
dbc->c_close(dbc);
db->close(db, 0);
db = 0;
rpmheadsize = 0;
rpmhead = 0;
- pool->solvables = xrealloc2(pool->solvables, (pool->nsolvables + nrpmids), sizeof(Solvable));
- memset(pool->solvables + pool->nsolvables, 0, nrpmids * sizeof(Solvable));
- repo->rpmdbid = calloc(nrpmids, sizeof(unsigned int));
-
refhash = 0;
refmask = 0;
if (ref)
refhash[h] = i + 1; /* make it non-zero */
}
}
- s = pool->solvables + pool->nsolvables;
+
+ repo->rpmdbid = xcalloc(nrpmids, sizeof(unsigned int));
+ id = repo_add_solvable_block(repo, nrpmids);
+ s = pool->solvables + id;
+
for (i = 0; i < nrpmids; i++, rp++, s++)
{
s->repo = repo;
+ repo->nsolvables++;
dbid = rp->dbid;
repo->rpmdbid[i] = dbid;
if (refhash)
}
if (rpmhead)
free(rpmhead);
- pool->nsolvables += nrpmids;
- repo->nsolvables += nrpmids;
- repo->end += nrpmids;
-
if (db)
db->close(db, 0);
}
int acontent;
int docontent;
int numpacks;
- int pack;
Pool *pool;
Repo *repo;
- Solvable *start;
+ Solvable *solvable;
struct stateswitch *swtab[NUMSTATES];
enum state sbtab[NUMSTATES];
};
{
struct parsedata *pd = userData;
Pool *pool = pd->pool;
- Solvable *s = pd->start ? pd->start + pd->pack : 0;
+ Solvable *s = pd->solvable;
struct stateswitch *sw;
+ Id id;
if (pd->depth != pd->statedepth)
{
if (!strcmp(*atts, "packages"))
{
pd->numpacks = atoi(atts[1]);
+ if (pd->numpacks < 0)
+ pd->numpacks = 0;
#if 0
fprintf(stderr, "numpacks: %d\n", pd->numpacks);
#endif
- pool->solvables = xrealloc2(pool->solvables, (pool->nsolvables + pd->numpacks), sizeof(Solvable));
- pd->start = pool->solvables + pool->nsolvables;
- memset(pd->start, 0, pd->numpacks * sizeof(Solvable));
+ id = repo_add_solvable_block(pd->repo, pd->numpacks);
+ pd->solvable = pool->solvables + id;
}
}
break;
case STATE_PACKAGE:
- if (pd->pack >= pd->numpacks)
+ if (pd->numpacks > 0)
+ pd->numpacks--;
+ else
{
- fprintf(stderr, "repomd lied about the package number\n");
- exit(1);
+ id = repo_add_solvable(pd->repo);
+ pd->solvable = pool->solvables + id;
}
#if 0
- fprintf(stderr, "package #%d\n", pd->pack);
+ fprintf(stderr, "package #%d\n", pd->solvable - pool->solvables);
#endif
break;
case STATE_VERSION:
{
struct parsedata *pd = userData;
Pool *pool = pd->pool;
- Solvable *s = pd->start ? pd->start + pd->pack : 0;
+ Solvable *s = pd->solvable;
Id id;
if (pd->depth != pd->statedepth)
{
case STATE_PACKAGE:
s->repo = pd->repo;
+ pd->repo->nsolvables++;
if (!s->arch)
s->arch = ARCH_NOARCH;
if (s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
s->provides = repo_addid_dep(pd->repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
s->supplements = repo_fix_legacy(pd->repo, s->provides, s->supplements);
- pd->pack++;
+ pd->solvable++;
break;
case STATE_NAME:
s->name = str2id(pool, pd->content, 1);
int i, l;
struct stateswitch *sw;
- if (!repo->start || repo->start == repo->end)
- repo->start = pool->nsolvables;
- repo->end = pool->nsolvables;
-
memset(&pd, 0, sizeof(pd));
for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
{
break;
}
XML_ParserFree(parser);
-
- pool->nsolvables += pd.pack;
- repo->nsolvables += pd.pack;
- repo->end += pd.pack;
-
+ if (pd.numpacks)
+ repo_free_solvable_block(repo, pd.solvable - pool->solvables, pd.numpacks, 1);
free(pd.content);
}
#include "attr_store.h"
#include "repo_susetags.h"
-#define PACK_BLOCK 255
-
static int
split(char *l, char **sp, int m)
{
int pack;
char *sp[5];
struct parsedata pd;
+ Id id;
- if (!repo->start || repo->start == repo->end)
- repo->start = pool->nsolvables;
- repo->end = pool->nsolvables;
-
- attr = new_store (pool);
+ if (with_attr)
+ attr = new_store(pool);
memset(&pd, 0, sizeof(pd));
line = malloc(1024);
aline = 1024;
pd.kind = 0;
if (line[3] == 't')
pd.kind = "pattern";
- if ((pack & PACK_BLOCK) == 0)
- {
- pool->solvables = realloc(pool->solvables, (pool->nsolvables + pack + PACK_BLOCK + 1) * sizeof(Solvable));
- memset(pool->solvables + pool->nsolvables + pack, 0, (PACK_BLOCK + 1) * sizeof(Solvable));
- }
- s = pool->solvables + pool->nsolvables + pack;
+ id = repo_add_solvable(repo);
+ s = pool->solvables + id;
s->repo = repo;
+ repo->nsolvables++;
last_found_pack = pack;
pack++;
if (split(line + 5, sp, 5) != 4)
if (s)
s->supplements = repo_fix_legacy(repo, s->provides, s->supplements);
- pool->nsolvables += pack;
- repo->nsolvables += pack;
- repo->end += pack;
if (pd.tmp)
free(pd.tmp);
free(line);
if (s->freshens)
write_idarray(fp, pool, needid, idarraydata + s->freshens);
if (repo->rpmdbid)
- write_u32(fp, repo->rpmdbid[i]);
+ write_u32(fp, repo->rpmdbid[i - repo->start]);
}
free(needid);