char *debugstr;
int debugstrl;
int debugstrf;
+ int userecommendsforchoices;
} Expander;
typedef Pool *BSSolv__pool;
*cidone = out->count;
}
+static void
+expander_updaterecommendedmap(Expander *xp, Map *recommended, int *recdone, Queue *out)
+{
+ Pool *pool = xp->pool;
+
+ int i;
+ Id p, pp, rec, *recp;
+ for (i = *recdone; i < out->count; i++)
+ {
+ Solvable *s;
+ s = pool->solvables + out->elements[i];
+ if (s->recommends)
+ {
+ MAPEXP(recommended, pool->nsolvables);
+ for (recp = s->repo->idarraydata + s->recommends; (rec = *recp++) != 0; )
+ FOR_PROVIDES(p, pp, rec)
+ MAPSET(recommended, p);
+ }
+ }
+ *recdone = out->count;
+}
+
static inline int
findconflictsinfo(Queue *conflictsinfo, Id p)
{
Queue todo, errors, cerrors, qq, posfoundq;
Map installed;
Map conflicts;
+ Map recommended;
Queue conflictsinfo;
int cidone;
+ int recdone;
Solvable *s;
Id q, p, pp;
int i, j, nerrors, doamb, ambcnt;
Id id, who, whon, pn;
Id conflprov, conflprovpc;
+ int haverecommended = 0;
+ int haverecommended_done = 0;
map_init(&installed, pool->nsolvables);
map_init(&conflicts, 0);
+ map_init(&recommended, 0);
queue_init(&conflictsinfo);
queue_init(&todo);
queue_init(&qq);
queue_empty(out);
cidone = 0;
-
+ recdone = 0;
if (inconfl)
{
for (i = 0; i < inconfl->count; i += 2)
who = queue_shift(&todo);
if (ambcnt == 0)
{
- if (doamb)
+ if (doamb >= 2)
break; /* amb pass had no progress, stop */
+ doamb = xp->userecommendsforchoices ? doamb + 1 : 3;
+ if (doamb == 1 && !haverecommended)
+ {
+ for (i = haverecommended_done; i < out->count; i++)
+ if (pool->solvables[out->elements[i]].recommends)
+ haverecommended = 1;
+ haverecommended_done = out->count;
+ if (!haverecommended)
+ doamb = 3;
+ }
if (xp->debug)
- expander_dbg(xp, "now doing undecided dependencies\n");
- doamb = 1; /* start amb pass */
+ {
+ if (doamb == 2)
+ expander_dbg(xp, "now doing undecided dependencies with recommends\n");
+ else
+ expander_dbg(xp, "now doing undecided dependencies\n");
+ }
ambcnt = todo.count;
}
else
break;
}
}
+
+ if (qq.count > 1 && doamb == 1)
+ {
+ queue_push2(&todo, id, who);
+ continue;
+ }
+
+ /* prioritize recommended packages. */
+ if (qq.count > 1 && doamb == 2)
+ {
+ expander_updaterecommendedmap(xp, &recommended, &recdone, out);
+ if (recommended.size)
+ {
+ for (i = j = 0; i < qq.count; i++)
+ if (MAPTST(&recommended, qq.elements[i]))
+ qq.elements[j++] = qq.elements[i];
+ if (j)
+ queue_truncate(&qq, j);
+ }
+ }
+
+
if (qq.count > 1)
{
queue_push(&cerrors, ERROR_CHOICE);
}
map_free(&installed);
map_free(&conflicts);
+ map_free(&recommended);
queue_free(&conflictsinfo);
nerrors = 0;
if (errors.count || cerrors.count)
sv = get_sv("Build::expand_dbg", FALSE);
if (sv && SvTRUE(sv))
xp->debug = 1;
+ xp->userecommendsforchoices = 1;
RETVAL = xp;
}
OUTPUT: