/*
+ * Copyright (c) 2007, Novell Inc.
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+/*
* pool.c
*
* The pool contains information about solvables
"solvable:name",
"solvable:arch",
"solvable:evr",
+ "solvable:vendor",
"solvable:provides",
"solvable:obsoletes",
"solvable:conflicts",
"rpm:dbid", /* direct key into rpmdb */
"solvable:prereqmarker",
"solvable:filemarker",
+ "namespace:installed",
+ "namespace:modalias",
+ "system:system",
"src",
"nosrc",
"noarch"
{
int count, totalsize = 0;
Pool *pool;
+ Solvable *s;
pool = (Pool *)xcalloc(1, sizeof(*pool));
pool->nrels = 1;
// pre-alloc space for a Solvable
- pool->solvables = (Solvable *)xcalloc(1, sizeof(Solvable));
- pool->nsolvables = 1;
-
+ pool->solvables = (Solvable *)xcalloc(2, sizeof(Solvable));
+ pool->nsolvables = 2;
+ queue_init(&pool->vendormap);
+ s = pool->solvables + SYSTEMSOLVABLE;
+ s->name = SYSTEM_SYSTEM;
+ s->arch = ARCH_NOARCH;
+ s->evr = ID_EMPTY;
return pool;
}
pool_free(Pool *pool)
{
int i;
- Source *source;
pool_freewhatprovides(pool);
pool_freeidhashes(pool);
- for (i = 0; i < pool->nsources; i++)
- {
- source = pool->sources[i];
- xfree(source->idarraydata);
- xfree(source->rpmdbid);
- xfree(source);
- }
+ pool_freeallrepos(pool, 1);
+ xfree(pool->id2arch);
xfree(pool->solvables);
- xfree(pool->sources);
xfree(pool->stringspace);
xfree(pool->strings);
xfree(pool->rels);
+ queue_free(&pool->vendormap);
+ for (i = 0; i < DEP2STRBUF; i++)
+ xfree(pool->dep2strbuf[i]);
xfree(pool);
}
+static Pool *pool_shrink_whatprovides_sortcmp_data;
+
+static int
+pool_shrink_whatprovides_sortcmp(const void *ap, const void *bp)
+{
+ int r;
+ Pool *pool = pool_shrink_whatprovides_sortcmp_data;
+ Id oa, ob, *da, *db;
+ oa = pool->whatprovides[*(Id *)ap];
+ ob = pool->whatprovides[*(Id *)bp];
+ if (oa == ob)
+ return *(Id *)ap - *(Id *)bp;
+ if (!oa)
+ return -1;
+ if (!ob)
+ return 1;
+ da = pool->whatprovidesdata + oa;
+ db = pool->whatprovidesdata + ob;
+ while (*db)
+ if ((r = (*da++ - *db++)) != 0)
+ return r;
+ if (*da)
+ return *da;
+ return *(Id *)ap - *(Id *)bp;
+}
+
+static void
+pool_shrink_whatprovides(Pool *pool)
+{
+ Id i, id;
+ Id *sorted;
+ Id lastid, *last, *dp, *lp;
+ Offset o;
+ int r;
+
+ if (pool->nstrings < 3)
+ return;
+ sorted = xmalloc2(pool->nstrings, sizeof(Id));
+ for (id = 0; id < pool->nstrings; id++)
+ sorted[id] = id;
+ pool_shrink_whatprovides_sortcmp_data = pool;
+ qsort(sorted + 1, pool->nstrings - 1, sizeof(Id), pool_shrink_whatprovides_sortcmp);
+ last = 0;
+ lastid = 0;
+ for (i = 1; i < pool->nstrings; i++)
+ {
+ id = sorted[i];
+ o = pool->whatprovides[id];
+ if (o == 0 || o == 1)
+ continue;
+ dp = pool->whatprovidesdata + o;
+ if (last)
+ {
+ lp = last;
+ while (*dp)
+ if (*dp++ != *lp++)
+ {
+ last = 0;
+ break;
+ }
+ if (last && *lp)
+ last = 0;
+ if (last)
+ {
+ pool->whatprovides[id] = -lastid;
+ continue;
+ }
+ }
+ last = pool->whatprovidesdata + o;
+ lastid = id;
+ }
+ xfree(sorted);
+ dp = pool->whatprovidesdata + 2;
+ for (id = 1; id < pool->nstrings; id++)
+ {
+ o = pool->whatprovides[id];
+ if (o == 0 || o == 1)
+ continue;
+ if ((Id)o < 0)
+ {
+ i = -(Id)o;
+ if (i >= id)
+ abort();
+ pool->whatprovides[id] = pool->whatprovides[i];
+ continue;
+ }
+ lp = pool->whatprovidesdata + o;
+ if (lp < dp)
+ abort();
+ pool->whatprovides[id] = dp - pool->whatprovidesdata;
+ while ((*dp++ = *lp++) != 0)
+ ;
+ }
+ o = dp - pool->whatprovidesdata;
+ if (pool->verbose)
+ printf("shrunk whatprovidesdata from %d to %d\n", pool->whatprovidesdataoff, o);
+ if (pool->whatprovidesdataoff == o)
+ return;
+ r = pool->whatprovidesdataoff - o;
+ pool->whatprovidesdataoff = o;
+ pool->whatprovidesdata = xrealloc(pool->whatprovidesdata, (o + pool->whatprovidesdataleft) * sizeof(Id));
+ if (r > pool->whatprovidesdataleft)
+ r = pool->whatprovidesdataleft;
+ memset(pool->whatprovidesdata + o, 0, r * sizeof(Id));
+}
+
+
/*
* pool_prepare()
*
pool_prepare(Pool *pool)
{
int i, num, np, extra;
- unsigned int n;
Offset off;
Solvable *s;
Id id;
- Offset *idp;
+ Offset *idp, n;
Offset *whatprovides;
Id *whatprovidesdata, *d;
whatprovides = (Offset *)xcalloc(num, sizeof(Offset));
/* count providers for each name */
-
- for (i = 1; i < pool->nsolvables; i++) /* loop over all, but first, solvables */
+ for (i = 1; i < pool->nsolvables; i++)
{
Id *pp;
s = pool->solvables + i;
- if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)
- continue; /* sources do not provide anything */
- if (pool->id2arch && (s->arch > pool->lastarch || !pool->id2arch[s->arch]))
- continue; /* architecture not installable */
- pp = s->provides;
- if (!pp) /* solvable does not provide anything */
+ if (!s->provides)
continue;
+ if (!pool_installable(pool, s))
+ continue;
+ pp = s->repo->idarraydata + s->provides;
while ((id = *pp++) != ID_NULL)
{
if (ISRELDEP(id))
{
Id *pp;
s = pool->solvables + i;
- if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)
- continue; /* sources do not provide anything */
- if (pool->id2arch && (s->arch > pool->lastarch || !pool->id2arch[s->arch]))
- continue; /* architecture not installable */
- pp = s->provides;
- if (!pp) /* solvable does not provide anything */
+ if (!s->provides)
+ continue;
+ if (!pool_installable(pool, s))
continue;
/* for all provides of this solvable */
+ pp = s->repo->idarraydata + s->provides;
while ((id = *pp++) != 0)
{
if (ISRELDEP(id))
*d = i; /* put solvable Id into data */
}
}
-
pool->whatprovides = whatprovides;
pool->whatprovidesdata = whatprovidesdata;
pool->whatprovidesdataoff = off;
pool->whatprovidesdataleft = extra;
+ pool_shrink_whatprovides(pool);
}
+
/******************************************************************************/
/*
}
+/******************************************************************************/
+
/*
- * addrangedep
+ * addrelproviders
*
- * add RangeDep to whatprovides
+ * add packages fulfilling the relation to whatprovides array
* no exact providers, do range match
*
*/
Id *
-addrelproviders(Pool *pool, Id d)
+pool_addrelproviders(Pool *pool, Id d)
{
Reldep *rd = GETRELDEP(pool, d);
Reldep *prd;
Id p, *pp, *pp2, *pp3;
d = GETRELID(pool, d);
- queueinit_buffer(&plist, buf, sizeof(buf)/sizeof(*buf));
+ queue_init_buffer(&plist, buf, sizeof(buf)/sizeof(*buf));
switch (flags)
{
case REL_AND:
for (pp3 = pp2; *pp3;)
if (*pp3++ == p)
{
- queuepush(&plist, p);
+ queue_push(&plist, p);
break;
}
}
case REL_OR:
pp = GET_PROVIDESP(name, p);
while ((p = *pp++) != 0)
- queuepush(&plist, p);
+ queue_push(&plist, p);
pp = GET_PROVIDESP(evr, p);
while ((p = *pp++) != 0)
- queuepushunique(&plist, p);
+ queue_pushunique(&plist, p);
break;
case REL_NAMESPACE:
- /* unknown namespace, just pass through */
- pp = GET_PROVIDESP(evr, p);
- while ((p = *pp++) != 0)
- queuepush(&plist, p);
+ if (pool->nscallback)
+ {
+ p = pool->nscallback(pool, pool->nscallbackdata, name, evr);
+ if (p > 1)
+ {
+ queue_free(&plist);
+ pool->whatprovides[d] = p;
+ return pool->whatprovidesdata + p;
+ }
+ if (p == 1)
+ queue_push(&plist, SYSTEMSOLVABLE);
+ }
break;
default:
break;
printf("addrelproviders: checking package %s\n", id2str(pool, pool->p[p].name));
#endif
/* solvable p provides name in some rels */
- for (pidp = pool->solvables[p].provides; (pid = *pidp++) != 0; )
+ pidp = pool->solvables[p].repo->idarraydata + pool->solvables[p].provides;
+ while ((pid = *pidp++) != 0)
{
int pflags;
Id pevr;
}
if (!pid)
continue; /* no rel match */
- queuepush(&plist, p);
+ queue_push(&plist, p);
}
+ /* make our system solvable provide all unknown rpmlib() stuff */
+ if (plist.count == 0 && !strncmp(id2str(pool, name), "rpmlib(", 7))
+ queue_push(&plist, SYSTEMSOLVABLE);
}
/* add providers to whatprovides */
#if 0
if (pool->verbose) printf("addrelproviders: adding %d packages to %d\n", plist.count, d);
#endif
pool->whatprovides[d] = pool_queuetowhatprovides(pool, &plist);
- queuefree(&plist);
+ queue_free(&plist);
return pool->whatprovidesdata + pool->whatprovides[d];
}
-
-/*
- * return source of solvable
- * or NULL
- */
-
-Source *
-pool_source(Pool *pool, Solvable *s)
-{
- int i;
- Source *source;
- int off = s - pool->solvables;
-
- for (i = 0; i < pool->nsources; i++)
- {
- source = pool->sources[i];
- if (off >= source->start
- && off < source->start+source->nsolvables)
- {
- return source;
- }
- }
- return NULL;
-}
-
// EOF