*
*/
-Id *
+Id
pool_addrelproviders(Pool *pool, Id d)
{
Reldep *rd = GETRELDEP(pool, d);
Id evr = rd->evr;
int flags = rd->flags;
Id pid, *pidp;
- Id p, *pp, *pp2, *pp3;
+ Id p, wp, *pp, *pp2, *pp3;
d = GETRELID(d);
queue_init_buffer(&plist, buf, sizeof(buf)/sizeof(*buf));
{
case REL_AND:
case REL_WITH:
- pp = pool_whatprovides(pool, name);
- pp2 = pool_whatprovides(pool, evr);
+ pp = pool->whatprovidesdata + pool_whatprovides(pool, name);
+ pp2 = pool->whatprovidesdata + pool_whatprovides(pool, evr);
while ((p = *pp++) != 0)
{
for (pp3 = pp2; *pp3;)
}
break;
case REL_OR:
- pp = pool_whatprovides(pool, name);
+ pp = pool->whatprovidesdata + pool_whatprovides(pool, name);
while ((p = *pp++) != 0)
queue_push(&plist, p);
- pp = pool_whatprovides(pool, evr);
+ pp = pool->whatprovidesdata + pool_whatprovides(pool, evr);
while ((p = *pp++) != 0)
queue_pushunique(&plist, p);
break;
case REL_NAMESPACE:
if (name == NAMESPACE_OTHERPROVIDERS)
{
- pp = pool_whatprovides(pool, evr);
- pool->whatprovides_rel[d] = pp - pool->whatprovidesdata;
- return pp;
+ wp = pool_whatprovides(pool, evr);
+ pool->whatprovides_rel[d] = wp;
+ return wp;
}
if (pool->nscallback)
{
{
queue_free(&plist);
pool->whatprovides_rel[d] = p;
- return pool->whatprovidesdata + p;
+ return p;
}
if (p == 1)
queue_push(&plist, SYSTEMSOLVABLE);
}
break;
}
- pp = pp2 = pool_whatprovides(pool, name);
+ wp = pool_whatprovides(pool, name);
+ pp = pool->whatprovidesdata + wp;
while ((p = *pp++) != 0)
{
Solvable *s = pool->solvables + p;
if (s->arch == evr)
queue_push(&plist, p);
else
- pp2 = 0;
+ wp = 0;
+ }
+ if (wp)
+ {
+ pool->whatprovides_rel[d] = wp;
+ return wp;
}
- if (pp2)
- return pp2;
break;
default:
break;
#endif
if (flags && flags < 8)
{
- pp = pool_whatprovides(pool, name);
+ pp = pool->whatprovidesdata + pool_whatprovides(pool, name);
while (ISRELDEP(name))
{
rd = GETRELDEP(pool, name);
pool->whatprovides_rel[d] = pool_queuetowhatprovides(pool, &plist);
queue_free(&plist);
- return pool->whatprovidesdata + pool->whatprovides_rel[d];
+ return pool->whatprovides_rel[d];
}
/*************************************************************************/
repo_search(s->repo, sp, SOLVABLE_DISKUSAGE, 0, 0, solver_fill_DU_cb, &cbd);
if (!cbd.hasdu && oldinstalled)
{
- Id op, *opp;
+ Id op, opp;
/* no du data available, ignore data of all installed solvables we obsolete */
if (!ignoredu.map)
map_init(&ignoredu, oldinstalled->end - oldinstalled->start);
static inline int providedbyinstalled(Pool *pool, unsigned char *map, Id dep)
{
- Id p, *pp;
+ Id p, pp;
int r = 0;
FOR_PROVIDES(p, pp, dep)
{
conp = s->repo->idarraydata + s->conflicts;
while ((con = *conp++) != 0)
{
- dp = pool_whatprovides(pool, con);
+ dp = pool->whatprovidesdata + pool_whatprovides(pool, con);
for (; *dp; dp++)
map[p] |= 2; /* XXX: self conflict ? */
}
#include "policy.h"
#include "solverdebug.h"
-#define CODE10 0 /* set to '1' to enable patch atoms */
-
#define RULES_BLOCK 63
/********************************************************************
solver_splitprovides(Solver *solv, Id dep)
{
Pool *pool = solv->pool;
- Id p, *pp;
+ Id p, pp;
Reldep *rd;
Solvable *s;
{
#if 0
Pool *pool = solv->pool;
- Id p, *pp;
+ Id p, pp;
if (ISRELDEP(dep))
{
dep_possible(Solver *solv, Id dep, Map *m)
{
Pool *pool = solv->pool;
- Id p, *pp;
+ Id p, pp;
if (ISRELDEP(dep))
{
{
Pool *pool = solv->pool;
int i, j;
- Id how, select, what, p, *pp;
+ Id how, select, what, p, pp;
Solvable *s;
Repo *installed;
Rule *r;
Pool *pool = solv->pool;
Solvable *s, *sn;
Queue q;
- Id p, *pp, qbuf[64];
+ Id p, pp, qbuf[64];
sn = pool->solvables + n;
queue_init_buffer(&q, qbuf, sizeof(qbuf)/sizeof(*qbuf));
* 0 = yes, 1 = no
*/
int dontfix;
-#if CODE10
- int patchatom;
-#endif
/* Id var and pointer for each dependency
* (not used in parallel)
*/
Id rec, *recp;
Id sug, *sugp;
/* var and ptr for loops */
- Id p, *pp;
+ Id p, pp;
/* ptr to 'whatprovides' */
Id *dp;
/* Id for current solvable 's' */
continue;
/* find list of solvables providing 'req' */
- dp = pool_whatprovides(pool, req);
+ dp = pool->whatprovidesdata + pool_whatprovides(pool, req);
if (*dp == SYSTEMSOLVABLE) /* always installed */
continue;
-#if CODE10
- if (patchatom)
- {
- addpatchatomrequires(solv, s, dp, &workq, m);
- continue;
- }
-#endif
if (dontfix)
{
/* the strategy here is to not insist on dependencies
/* we treat conflicts in patches a bit differen:
* - nevr matching
* - multiversion handling
+ * XXX: we should really handle this different, looking
+ * at the name is a bad hack
*/
if (!strncmp("patch:", id2str(pool, s->name), 6))
ispatch = 1;
if (solv->decisionmap[i] > 0)
{
/* installed, check for recommends */
- Id *recp, rec, *pp, p;
+ Id *recp, rec, pp, p;
s = pool->solvables + i;
if (solv->ignorealreadyrecommended && s->repo == solv->installed)
continue;
Rule *r;
Solvable *s;
int dontfix = 0;
- Id p, d, w2, *pp, req, *reqp, con, *conp, obs, *obsp, *dp;
+ Id p, d, w2, pp, req, *reqp, con, *conp, obs, *obsp, *dp;
assert(rid > 0);
if (rid >= solv->jobrules && rid < solv->jobrules_end)
{
if (req == SOLVABLE_PREREQMARKER)
continue;
- dp = pool_whatprovides(pool, req);
+ dp = pool->whatprovidesdata + pool_whatprovides(pool, req);
if (*dp == 0)
break;
}
{
if (req == SOLVABLE_PREREQMARKER)
continue;
- dp = pool_whatprovides(pool, req);
+ dp = pool->whatprovidesdata + pool_whatprovides(pool, req);
if (d == 0)
{
if (*dp == r->w2 && dp[1] == 0)
Pool *pool = solv->pool;
Solvable *s;
Repo *installed = solv->installed;
- Id p, *pp, obs, *obsp, *obsoletes, *obsoletes_data;
+ Id p, pp, obs, *obsp, *obsoletes, *obsoletes_data;
int i, n;
if (!installed || !installed->nsolvables)
int oldnrules;
Map addedmap; /* '1' == have rpm-rules for solvable */
Map installcandidatemap;
- Id how, what, select, name, weak, p, *pp, d;
+ Id how, what, select, name, weak, p, pp, d;
Queue q, redoq;
Solvable *s;
int goterase;
* solver run */
if (redoq.count || solv->dontinstallrecommended || !solv->dontshowinstalledrecommended || solv->ignorealreadyrecommended)
{
- Id rec, *recp, p, *pp;
+ Id rec, *recp, p, pp;
/* create map of all recommened packages */
solv->recommends_index = -1;
if (1)
{
- Id sug, *sugp, p, *pp;
+ Id sug, *sugp, p, pp;
/* create map of all suggests that are still open */
solv->recommends_index = -1;
return change;
}
+#define FIND_INVOLVED_DEBUG 0
+void
+solver_find_involved(Solver *solv, Queue *installedq, Solvable *ts, Queue *q)
+{
+ Pool *pool = solv->pool;
+ Map im;
+ Map installedm;
+ Solvable *s;
+ Queue iq;
+ Queue installedq_internal;
+ Id tp, ip, p, pp, req, *reqp, sup, *supp;
+ int i, count;
+
+ tp = ts - pool->solvables;
+ queue_init(&iq);
+ queue_init(&installedq_internal);
+ map_init(&im, pool->nsolvables);
+ map_init(&installedm, pool->nsolvables);
+
+ if (!installedq)
+ {
+ installedq = &installedq_internal;
+ if (solv->installed)
+ {
+ for (ip = solv->installed->start; ip < solv->installed->end; ip++)
+ {
+ s = pool->solvables + ip;
+ if (s->repo != solv->installed)
+ continue;
+ queue_push(installedq, ip);
+ }
+ }
+ }
+ for (i = 0; i < installedq->count; i++)
+ {
+ ip = installedq->elements[i];
+ MAPSET(&installedm, ip);
+ MAPSET(&im, ip);
+ }
+
+ queue_push(&iq, ts - pool->solvables);
+ while (iq.count)
+ {
+ ip = queue_shift(&iq);
+ if (!MAPTST(&im, ip))
+ continue;
+ if (!MAPTST(&installedm, ip))
+ continue;
+ MAPCLR(&im, ip);
+ s = pool->solvables + ip;
+#if FIND_INVOLVED_DEBUG
+ printf("hello %s\n", solvable2str(pool, s));
+#endif
+ if (s->requires)
+ {
+ reqp = s->repo->idarraydata + s->requires;
+ while ((req = *reqp++) != 0)
+ {
+ if (req == SOLVABLE_PREREQMARKER)
+ continue;
+ /* count number of installed packages that match */
+ count = 0;
+ FOR_PROVIDES(p, pp, req)
+ if (MAPTST(&installedm, p))
+ count++;
+ if (count > 1)
+ continue;
+ FOR_PROVIDES(p, pp, req)
+ {
+ if (MAPTST(&im, p))
+ {
+#if FIND_INVOLVED_DEBUG
+ printf("%s requires %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p));
+#endif
+ queue_push(&iq, p);
+ }
+ }
+ }
+ }
+ if (s->recommends)
+ {
+ reqp = s->repo->idarraydata + s->recommends;
+ while ((req = *reqp++) != 0)
+ {
+ count = 0;
+ FOR_PROVIDES(p, pp, req)
+ if (MAPTST(&installedm, p))
+ count++;
+ if (count > 1)
+ continue;
+ FOR_PROVIDES(p, pp, req)
+ {
+ if (MAPTST(&im, p))
+ {
+#if FIND_INVOLVED_DEBUG
+ printf("%s recommends %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p));
+#endif
+ queue_push(&iq, p);
+ }
+ }
+ }
+ }
+ if (!iq.count)
+ {
+ /* supplements pass */
+ for (i = 0; i < installedq->count; i++)
+ {
+ ip = installedq->elements[i];
+ s = pool->solvables + ip;
+ if (!s->supplements)
+ continue;
+ if (!MAPTST(&im, ip))
+ continue;
+ supp = s->repo->idarraydata + s->supplements;
+ while ((sup = *supp++) != 0)
+ if (!dep_possible(solv, sup, &im) && dep_possible(solv, sup, &installedm))
+ break;
+ /* no longer supplemented, also erase */
+ if (sup)
+ {
+#if FIND_INVOLVED_DEBUG
+ printf("%s supplemented\n", solvable2str(pool, pool->solvables + ip));
+#endif
+ queue_push(&iq, ip);
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < installedq->count; i++)
+ {
+ ip = installedq->elements[i];
+ if (MAPTST(&im, ip))
+ queue_push(&iq, ip);
+ }
+
+ while (iq.count)
+ {
+ ip = queue_shift(&iq);
+ if (!MAPTST(&installedm, ip))
+ continue;
+ s = pool->solvables + ip;
+#if FIND_INVOLVED_DEBUG
+ printf("bye %s\n", solvable2str(pool, s));
+#endif
+ if (s->requires)
+ {
+ reqp = s->repo->idarraydata + s->requires;
+ while ((req = *reqp++) != 0)
+ {
+ FOR_PROVIDES(p, pp, req)
+ {
+ if (!MAPTST(&im, p))
+ {
+ if (p == tp)
+ continue;
+#if FIND_INVOLVED_DEBUG
+ printf("%s requires %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p));
+#endif
+ MAPSET(&im, p);
+ queue_push(&iq, p);
+ }
+ }
+ }
+ }
+ if (s->recommends)
+ {
+ reqp = s->repo->idarraydata + s->recommends;
+ while ((req = *reqp++) != 0)
+ {
+ FOR_PROVIDES(p, pp, req)
+ {
+ if (!MAPTST(&im, p))
+ {
+ if (p == tp)
+ continue;
+#if FIND_INVOLVED_DEBUG
+ printf("%s recommends %s\n", solvable2str(pool, pool->solvables + ip), solvable2str(pool, pool->solvables + p));
+#endif
+ MAPSET(&im, p);
+ queue_push(&iq, p);
+ }
+ }
+ }
+ }
+ if (!iq.count)
+ {
+ /* supplements pass */
+ for (i = 0; i < installedq->count; i++)
+ {
+ ip = installedq->elements[i];
+ if (ip == tp)
+ continue;
+ s = pool->solvables + ip;
+ if (!s->supplements)
+ continue;
+ if (MAPTST(&im, ip))
+ continue;
+ supp = s->repo->idarraydata + s->supplements;
+ while ((sup = *supp++) != 0)
+ if (dep_possible(solv, sup, &im))
+ break;
+ if (sup)
+ {
+#if FIND_INVOLVED_DEBUG
+ printf("%s supplemented\n", solvable2str(pool, pool->solvables + ip));
+#endif
+ MAPSET(&im, ip);
+ queue_push(&iq, ip);
+ }
+ }
+ }
+ }
+
+ queue_free(&iq);
+
+ /* convert map into result */
+ for (i = 0; i < installedq->count; i++)
+ {
+ ip = installedq->elements[i];
+ if (MAPTST(&im, ip))
+ continue;
+ if (ip == ts - pool->solvables)
+ continue;
+ queue_push(q, ip);
+ }
+ map_free(&im);
+ map_free(&installedm);
+ queue_free(&installedq_internal);
+}
+
/* EOF */
solver_dep_fulfilled(Solver *solv, Id dep)
{
Pool *pool = solv->pool;
- Id p, *pp;
+ Id p, pp;
if (ISRELDEP(dep))
{
void solver_calc_duchanges(Solver *solv, DUChanges *mps, int nmps);
int solver_calc_installsizechange(Solver *solv);
+void solver_find_involved(Solver *solv, Queue *installedq, Solvable *s, Queue *q);
+
static inline void
solver_create_state_maps(Solver *solv, Map *installedmap, Map *conflictsmap)
{
pool_create_state_maps(solv->pool, &solv->decisionq, installedmap, conflictsmap);
}
+/* iterate over all literals of a rule */
+/* WARNING: loop body must not relocate whatprovidesdata, e.g. by
+ * looking up the providers of a dependency */
#define FOR_RULELITERALS(l, dp, r) \
for (l = r->d < 0 ? -r->d - 1 : r->d, \
dp = !l ? &r->w2 : pool->whatprovidesdata + l, \
l = r->p; l; l = (dp != &r->w2 + 1 ? *dp++ : 0))
+/* iterate over all packages selected by a job */
#define FOR_JOB_SELECT(p, pp, select, what) \
- for (pp = (select == SOLVER_SOLVABLE ? pool->whatprovidesdata : \
- select == SOLVER_SOLVABLE_ONE_OF ? pool->whatprovidesdata + what : \
+ for (pp = (select == SOLVER_SOLVABLE ? 0 : \
+ select == SOLVER_SOLVABLE_ONE_OF ? what : \
pool_whatprovides(pool, what)), \
- p = (select == SOLVER_SOLVABLE ? what : *pp++) ; p ; p = *pp++) \
+ p = (select == SOLVER_SOLVABLE ? what : pool->whatprovidesdata[pp++]) ; p ; p = pool->whatprovidesdata[pp++]) \
if (select != SOLVER_SOLVABLE_NAME || pool_match_nevr(pool, pool->solvables + p, what))
#ifdef __cplusplus