solv_free(pool->tmpspace.buf[i]);
for (i = 0; i < pool->nlanguages; i++)
free((char *)pool->languages[i]);
- solv_free(pool->languages);
+ solv_free((void *)pool->languages);
solv_free(pool->languagecache);
solv_free(pool->errstr);
solv_free(pool->rootdir);
pool_free_solvable_block(pool, 2, pool->nsolvables - 2, reuseids);
}
-#ifdef MULTI_SEMANTICS
-void
+int
pool_setdisttype(Pool *pool, int disttype)
{
+#ifdef MULTI_SEMANTICS
+ int olddisttype = pool->disttype;
+ switch(disttype)
+ {
+ case DISTTYPE_RPM:
+ pool->noarchid = ARCH_NOARCH;
+ break;
+ case DISTTYPE_DEB:
+ pool->noarchid = ARCH_ALL;
+ break;
+ case DISTTYPE_ARCH:
+ case DISTTYPE_HAIKU:
+ pool->noarchid = ARCH_ANY;
+ break;
+ default:
+ return -1;
+ }
pool->disttype = disttype;
- if (disttype == DISTTYPE_RPM)
- pool->noarchid = ARCH_NOARCH;
- if (disttype == DISTTYPE_DEB)
- pool->noarchid = ARCH_ALL;
- if (disttype == DISTTYPE_ARCH)
- pool->noarchid = ARCH_ANY;
- if (disttype == DISTTYPE_HAIKU)
- pool->noarchid = ARCH_ANY;
pool->solvables[SYSTEMSOLVABLE].arch = pool->noarchid;
-}
+ return olddisttype;
+#else
+ return pool->disttype == disttype ? disttype : -1;
#endif
+}
int
pool_get_flag(Pool *pool, int flag)
return pool->noobsoletesmultiversion;
case POOL_FLAG_ADDFILEPROVIDESFILTERED:
return pool->addfileprovidesfiltered;
+ case POOL_FLAG_NOWHATPROVIDESAUX:
+ return pool->nowhatprovidesaux;
default:
break;
}
case POOL_FLAG_ADDFILEPROVIDESFILTERED:
pool->addfileprovidesfiltered = value;
break;
+ case POOL_FLAG_NOWHATPROVIDESAUX:
+ pool->nowhatprovidesaux = value;
+ break;
default:
break;
}
memset(pool->whatprovidesdata + o, 0, r * sizeof(Id));
}
+/* this gets rid of all the zeros in the aux */
+static void
+pool_shrink_whatprovidesaux(Pool *pool)
+{
+ int num = pool->whatprovidesauxoff;
+ Id id;
+ Offset newoff;
+ Id *op, *wp = pool->whatprovidesauxdata + 1;
+ int i;
+
+ for (i = 0; i < num; i++)
+ {
+ Offset o = pool->whatprovidesaux[i];
+ if (o < 2)
+ continue;
+ op = pool->whatprovidesauxdata + o;
+ pool->whatprovidesaux[i] = wp - pool->whatprovidesauxdata;
+ if (op < wp)
+ abort();
+ while ((id = *op++) != 0)
+ *wp++ = id;
+ }
+ newoff = wp - pool->whatprovidesauxdata;
+ pool->whatprovidesauxdata = solv_realloc(pool->whatprovidesauxdata, newoff * sizeof(Id));
+ POOL_DEBUG(SOLV_DEBUG_STATS, "shrunk whatprovidesauxdata from %d to %d\n", pool->whatprovidesauxdataoff, newoff);
+ pool->whatprovidesauxdataoff = newoff;
+}
+
/*
* pool_createwhatprovides()
Id id;
Offset *idp, n;
Offset *whatprovides;
- Id *whatprovidesdata, *d;
+ Id *whatprovidesdata, *dp, *whatprovidesauxdata;
+ Offset *whatprovidesaux;
Repo *installed = pool->installed;
unsigned int now;
whatprovidesdata = solv_calloc(off + extra, sizeof(Id));
whatprovidesdata[2] = SYSTEMSOLVABLE;
+ /* alloc aux vector */
+ whatprovidesauxdata = 0;
+ if (!pool->nowhatprovidesaux)
+ {
+ pool->whatprovidesaux = whatprovidesaux = solv_calloc(num, sizeof(Offset));
+ pool->whatprovidesauxoff = num;
+ pool->whatprovidesauxdataoff = off;
+ pool->whatprovidesauxdata = whatprovidesauxdata = solv_calloc(pool->whatprovidesauxdataoff, sizeof(Id));
+ }
+
/* now fill data for all provides */
for (i = pool->nsolvables - 1; i > 0; i--)
{
pp = s->repo->idarraydata + s->provides;
while ((id = *pp++) != 0)
{
+ Id auxid = id;
while (ISRELDEP(id))
{
Reldep *rd = GETRELDEP(pool, id);
id = rd->name;
}
- d = whatprovidesdata + whatprovides[id]; /* offset into whatprovidesdata */
- if (*d != i) /* don't add same solvable twice */
+ dp = whatprovidesdata + whatprovides[id]; /* offset into whatprovidesdata */
+ if (*dp != i) /* don't add same solvable twice */
{
- d[-1] = i;
+ dp[-1] = i;
whatprovides[id]--;
}
+ else
+ auxid = 1;
+ if (whatprovidesauxdata)
+ whatprovidesauxdata[whatprovides[id]] = auxid;
}
}
+ if (pool->whatprovidesaux)
+ memcpy(pool->whatprovidesaux, pool->whatprovides, num * sizeof(Id));
pool->whatprovidesdata = whatprovidesdata;
pool->whatprovidesdataoff = off;
pool->whatprovidesdataleft = extra;
pool_shrink_whatprovides(pool);
+ if (pool->whatprovidesaux)
+ pool_shrink_whatprovidesaux(pool);
POOL_DEBUG(SOLV_DEBUG_STATS, "whatprovides memory used: %d K id array, %d K data\n", (pool->ss.nstrings + pool->nrels + WHATPROVIDES_BLOCK) / (int)(1024/sizeof(Id)), (pool->whatprovidesdataoff + pool->whatprovidesdataleft) / (int)(1024/sizeof(Id)));
+ if (pool->whatprovidesaux)
+ POOL_DEBUG(SOLV_DEBUG_STATS, "whatprovidesaux memory used: %d K id array, %d K data\n", pool->whatprovidesauxoff / (int)(1024/sizeof(Id)), pool->whatprovidesauxdataoff / (int)(1024/sizeof(Id)));
queue_empty(&pool->lazywhatprovidesq);
if ((!pool->addedfileprovides && pool->disttype == DISTTYPE_RPM) || pool->addedfileprovides == 1)
if (pool->whatprovides[i] > 1)
queue_push2(&pool->lazywhatprovidesq, i, pool->whatprovides[i]);
pool->whatprovides[i] = 0;
+ if (pool->whatprovidesaux)
+ pool->whatprovidesaux[i] = 0; /* sorry */
}
POOL_DEBUG(SOLV_DEBUG_STATS, "lazywhatprovidesq size: %d entries\n", pool->lazywhatprovidesq.count / 2);
}
pool->whatprovidesdata = solv_free(pool->whatprovidesdata);
pool->whatprovidesdataoff = 0;
pool->whatprovidesdataleft = 0;
+ pool->whatprovidesaux = solv_free(pool->whatprovidesaux);
+ pool->whatprovidesauxdata = solv_free(pool->whatprovidesauxdata);
+ pool->whatprovidesauxoff = 0;
+ pool->whatprovidesauxdataoff = 0;
}
* returns: Offset into whatprovidesdata
*
*/
+
Id
-pool_queuetowhatprovides(Pool *pool, Queue *q)
+pool_ids2whatprovides(Pool *pool, Id *ids, int count)
{
Offset off;
- int count = q->count;
if (count == 0) /* queue empty -> 1 */
return 1;
- if (count == 1 && q->elements[0] == SYSTEMSOLVABLE)
+ if (count == 1 && *ids == SYSTEMSOLVABLE)
return 2;
/* extend whatprovidesdata if needed, +1 for 0-termination */
/* copy queue to next free slot */
off = pool->whatprovidesdataoff;
- memcpy(pool->whatprovidesdata + pool->whatprovidesdataoff, q->elements, count * sizeof(Id));
+ memcpy(pool->whatprovidesdata + pool->whatprovidesdataoff, ids, count * sizeof(Id));
/* adapt count and 0-terminate */
pool->whatprovidesdataoff += count;
return (Id)off;
}
+Id
+pool_queuetowhatprovides(Pool *pool, Queue *q)
+{
+ int count = q->count;
+ if (count == 0) /* queue empty -> 1 */
+ return 1;
+ if (count == 1 && q->elements[0] == SYSTEMSOLVABLE)
+ return 2;
+ return pool_ids2whatprovides(pool, q->elements, count);
+}
+
/*************************************************************************/
case REL_AND:
case REL_OR:
+ case REL_COND:
+ if (flags == REL_COND)
+ {
+ if (ISRELDEP(evr))
+ {
+ Reldep *rd2 = GETRELDEP(pool, evr);
+ evr = rd2->flags == REL_ELSE ? rd2->evr : 0;
+ }
+ else
+ evr = 0; /* assume cond is true */
+ }
wp = pool_whatprovides(pool, name);
if (!pool->whatprovidesdata[wp])
- wp = pool_whatprovides(pool, evr);
- else
+ wp = evr ? pool_whatprovides(pool, evr) : 1;
+ else if (evr)
{
/* sorted merge */
pp2 = pool_whatprovides_ptr(pool, evr);
}
break;
- case REL_COND:
- /* assume the condition is true */
- wp = pool_whatprovides(pool, name);
- break;
-
case REL_NAMESPACE:
if (name == NAMESPACE_OTHERPROVIDERS)
{
}
else if (flags)
{
+ Id *ppaux = 0;
/* simple version comparison relation */
#if 0
POOL_DEBUG(SOLV_DEBUG_STATS, "addrelproviders: what provides %s?\n", pool_dep2str(pool, name));
#endif
pp = pool_whatprovides_ptr(pool, name);
+ if (!ISRELDEP(name) && name < pool->whatprovidesauxoff)
+ ppaux = pool->whatprovidesaux[name] ? pool->whatprovidesauxdata + pool->whatprovidesaux[name] : 0;
while (ISRELDEP(name))
{
rd = GETRELDEP(pool, name);
while ((p = *pp++) != 0)
{
Solvable *s = pool->solvables + p;
+ if (ppaux)
+ {
+ pid = *ppaux++;
+ if (pid && pid != 1)
+ {
+#if 0
+ POOL_DEBUG(SOLV_DEBUG_STATS, "addrelproviders: aux hit %d %s\n", p, pool_dep2str(pool, pid));
+#endif
+ if (!ISRELDEP(pid))
+ {
+ if (pid != name)
+ continue; /* wrong provides name */
+ if (pool->disttype == DISTTYPE_DEB)
+ continue; /* unversioned provides can never match versioned deps */
+ }
+ else
+ {
+ prd = GETRELDEP(pool, pid);
+ if (prd->name != name)
+ continue; /* wrong provides name */
+ /* right package, both deps are rels. check flags/evr */
+ if (!pool_match_flags_evr(pool, prd->flags, prd->evr, flags, evr))
+ continue;
+ }
+ queue_push(&plist, p);
+ continue;
+ }
+ }
if (!s->provides)
{
/* no provides - check nevr */
dep = rd->name;
else if (rd->flags == REL_NAMESPACE)
{
- if (rd->name == NAMESPACE_INSTALLED || rd->name == NAMESPACE_SPLITPROVIDES)
+ if (rd->name == NAMESPACE_SPLITPROVIDES)
{
csf = isf;
if (!csf || MAPTST(&csf->seen, sid))
map_init(&cbd->useddirs, data->dirpool.ndirs + 1);
if (!cbd->dirs)
{
- cbd->dirs= solv_malloc2(cbd->nfiles, sizeof(char *));
+ cbd->dirs = solv_malloc2(cbd->nfiles, sizeof(char *));
cbd->names = solv_malloc2(cbd->nfiles, sizeof(char *));
for (i = 0; i < cbd->nfiles; i++)
{
if (value->id >= data->dirpool.ndirs || !MAPTST(&cbd->useddirs, value->id))
return 0;
for (i = 0; i < cbd->nfiles; i++)
- if (cbd->dids[i] != value->id && !strcmp(cbd->names[i], value->str))
- break;
- if (i < cbd->nfiles)
- s->provides = repo_addid_dep(s->repo, s->provides, cbd->ids[i], SOLVABLE_FILEMARKER);
+ if (cbd->dids[i] == value->id && !strcmp(cbd->names[i], value->str))
+ s->provides = repo_addid_dep(s->repo, s->provides, cbd->ids[i], SOLVABLE_FILEMARKER);
return 0;
}
pool->languagecacheother = 0;
for (i = 0; i < pool->nlanguages; i++)
free((char *)pool->languages[i]);
- pool->languages = solv_free(pool->languages);
+ pool->languages = solv_free((void *)pool->languages);
pool->nlanguages = nlanguages;
if (!nlanguages)
return;
cbd->mps[mp].kbytes += value->num;
cbd->mps[mp].files += value->num2;
}
- else
+ else if (!(cbd->mps[mp].flags & DUCHANGES_ONLYADD))
{
cbd->mps[mp].kbytes -= value->num;
cbd->mps[mp].files -= value->num2;
struct mptree *mptree;
struct ducbdata cbd;
Solvable *s;
- int sp;
+ int i, sp;
Map ignoredu;
Repo *oldinstalled = pool->installed;
+ int haveonlyadd = 0;
map_init(&ignoredu, 0);
mptree = create_mptree(mps, nmps);
+ for (i = 0; i < nmps; i++)
+ if ((mps[i].flags & DUCHANGES_ONLYADD) != 0)
+ haveonlyadd = 1;
cbd.mps = mps;
cbd.dirmap = 0;
cbd.nmap = 0;
if (!cbd.hasdu && oldinstalled)
{
Id op, opp;
+ int didonlyadd = 0;
/* no du data available, ignore data of all installed solvables we obsolete */
if (!ignoredu.size)
map_grow(&ignoredu, oldinstalled->end - oldinstalled->start);
+ FOR_PROVIDES(op, opp, s->name)
+ {
+ Solvable *s2 = pool->solvables + op;
+ if (!pool->implicitobsoleteusesprovides && s->name != s2->name)
+ continue;
+ if (pool->implicitobsoleteusescolors && !pool_colormatch(pool, s, s2))
+ continue;
+ if (op >= oldinstalled->start && op < oldinstalled->end)
+ {
+ MAPSET(&ignoredu, op - oldinstalled->start);
+ if (haveonlyadd && pool->solvables[op].repo == oldinstalled && !didonlyadd)
+ {
+ repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
+ cbd.addsub = -1;
+ repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
+ cbd.addsub = 1;
+ didonlyadd = 1;
+ }
+ }
+ }
if (s->obsoletes)
{
Id obs, *obsp = s->repo->idarraydata + s->obsoletes;
while ((obs = *obsp++) != 0)
FOR_PROVIDES(op, opp, obs)
- if (op >= oldinstalled->start && op < oldinstalled->end)
- MAPSET(&ignoredu, op - oldinstalled->start);
+ {
+ Solvable *s2 = pool->solvables + op;
+ if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, s2, obs))
+ continue;
+ if (pool->obsoleteusescolors && !pool_colormatch(pool, s, s2))
+ continue;
+ if (op >= oldinstalled->start && op < oldinstalled->end)
+ {
+ MAPSET(&ignoredu, op - oldinstalled->start);
+ if (haveonlyadd && pool->solvables[op].repo == oldinstalled && !didonlyadd)
+ {
+ repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
+ cbd.addsub = -1;
+ repo_search(oldinstalled, op, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
+ cbd.addsub = 1;
+ didonlyadd = 1;
+ }
+ }
+ }
}
- FOR_PROVIDES(op, opp, s->name)
- if (pool->solvables[op].name == s->name)
- if (op >= oldinstalled->start && op < oldinstalled->end)
- MAPSET(&ignoredu, op - oldinstalled->start);
}
}
cbd.addsub = -1;
if (p)
queue_push(&q, p);
pool->whatprovides[id] = pool_queuetowhatprovides(pool, &q);
+ if (id < pool->whatprovidesauxoff)
+ pool->whatprovidesaux[id] = 0; /* sorry */
queue_free(&q);
}