+
+ if (solv->bestupdatemap_all || solv->bestupdatemap.size)
+ {
+ FOR_REPO_SOLVABLES(installed, p, s)
+ {
+ Id d, p2, pp2;
+ if (!solv->updatemap_all && (!solv->updatemap.size || !MAPTST(&solv->updatemap, p - installed->start)))
+ continue;
+ if (!solv->bestupdatemap_all && (!solv->bestupdatemap.size || !MAPTST(&solv->bestupdatemap, p - installed->start)))
+ continue;
+ queue_empty(&q);
+ if (solv->bestobeypolicy)
+ r = solv->rules + solv->updaterules + (p - installed->start);
+ else
+ {
+ r = solv->rules + solv->featurerules + (p - installed->start);
+ if (!r->p) /* identical to update rule? */
+ r = solv->rules + solv->updaterules + (p - installed->start);
+ }
+ if (solv->specialupdaters && (d = solv->specialupdaters[p - installed->start]) != 0 && r == solv->rules + solv->updaterules + (p - installed->start))
+ {
+ /* need to check specialupdaters */
+ if (r->p == p) /* be careful with the dup case */
+ queue_push(&q, p);
+ while ((p2 = pool->whatprovidesdata[d++]) != 0)
+ queue_push(&q, p2);
+ }
+ else
+ {
+ FOR_RULELITERALS(p2, pp2, r)
+ if (p2 > 0)
+ queue_push(&q, p2);
+ }
+ if (solv->update_targets && solv->update_targets->elements[p - installed->start])
+ prune_to_update_targets(solv, solv->update_targets->elements + solv->update_targets->elements[p - installed->start], &q);
+ if (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))
+ prune_to_dup_packages(solv, p, &q);
+ /* select best packages, just look at prio and version */
+ policy_filter_unwanted(solv, &q, POLICY_MODE_RECOMMEND);
+ if (!q.count)
+ continue; /* orphaned */
+ if (solv->bestobeypolicy)
+ {
+ /* also filter the best of the feature rule packages and add them */
+ r = solv->rules + solv->featurerules + (p - installed->start);
+ if (r->p)
+ {
+ int j;
+ queue_empty(&q2);
+ FOR_RULELITERALS(p2, pp2, r)
+ if (p2 > 0)
+ queue_push(&q2, p2);
+ if (solv->update_targets && solv->update_targets->elements[p - installed->start])
+ prune_to_update_targets(solv, solv->update_targets->elements + solv->update_targets->elements[p - installed->start], &q2);
+ if (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p))
+ prune_to_dup_packages(solv, p, &q2);
+ policy_filter_unwanted(solv, &q2, POLICY_MODE_RECOMMEND);
+ for (j = 0; j < q2.count; j++)
+ queue_pushunique(&q, q2.elements[j]);
+ }
+ }
+ p2 = queue_shift(&q);
+ if (q.count < 2)
+ solver_addrule(solv, p2, q.count ? q.elements[0] : 0, 0);
+ else
+ solver_addrule(solv, p2, 0, pool_queuetowhatprovides(pool, &q));
+ queue_push(&r2pkg, p);
+ }
+ }
+ if (r2pkg.count)
+ solv->bestrules_pkg = solv_memdup2(r2pkg.elements, r2pkg.count, sizeof(Id));
+ solv->bestrules_end = solv->nrules;
+ queue_free(&q);
+ queue_free(&q2);
+ queue_free(&r2pkg);
+}
+
+
+
+
+/* yumobs rule handling */
+
+static void
+find_obsolete_group(Solver *solv, Id obs, Queue *q)
+{
+ Pool *pool = solv->pool;
+ Queue qn;
+ Id p2, pp2, op, *opp, opp2;
+ int i, j, qnc, ncnt;
+
+ queue_empty(q);
+ FOR_PROVIDES(p2, pp2, obs)
+ {
+ Solvable *s2 = pool->solvables + p2;
+ if (s2->repo != pool->installed)
+ continue;
+ if (!pool->obsoleteusesprovides && !pool_match_nevr(pool, pool->solvables + p2, obs))
+ continue;
+ /* we obsolete installed package s2 with obs. now find all other packages that have the same dep */
+ for (opp = solv->obsoletes_data + solv->obsoletes[p2 - solv->installed->start]; (op = *opp++) != 0;)
+ {
+ Solvable *os = pool->solvables + op;
+ Id obs2, *obsp2;
+ if (!os->obsoletes)
+ continue;
+ if (pool->obsoleteusescolors && !pool_colormatch(pool, s2, os))
+ continue;
+ obsp2 = os->repo->idarraydata + os->obsoletes;
+ while ((obs2 = *obsp2++) != 0)
+ if (obs2 == obs)
+ break;
+ if (obs2)
+ queue_pushunique(q, op);
+ }
+ /* also search packages with the same name */
+ FOR_PROVIDES(op, opp2, s2->name)
+ {
+ Solvable *os = pool->solvables + op;
+ Id obs2, *obsp2;
+ if (os->name != s2->name)
+ continue;
+ if (!os->obsoletes)
+ continue;
+ if (pool->obsoleteusescolors && !pool_colormatch(pool, s2, os))
+ continue;
+ obsp2 = os->repo->idarraydata + os->obsoletes;
+ while ((obs2 = *obsp2++) != 0)
+ if (obs2 == obs)
+ break;
+ if (obs2)
+ queue_pushunique(q, op);
+ }
+ }
+ /* find names so that we can build groups */
+ queue_init_clone(&qn, q);
+ prune_to_best_version(solv->pool, &qn);
+#if 0
+{
+ for (i = 0; i < qn.count; i++)
+ printf(" + %s\n", pool_solvid2str(pool, qn.elements[i]));
+}
+#endif
+ /* filter into name groups */
+ qnc = qn.count;
+ if (qnc == 1)
+ {
+ queue_free(&qn);
+ queue_empty(q);
+ return;
+ }
+ ncnt = 0;
+ for (i = 0; i < qnc; i++)
+ {
+ Id n = pool->solvables[qn.elements[i]].name;
+ int got = 0;
+ for (j = 0; j < q->count; j++)
+ {
+ Id p = q->elements[j];
+ if (pool->solvables[p].name == n)
+ {
+ queue_push(&qn, p);
+ got = 1;
+ }
+ }
+ if (got)
+ {
+ queue_push(&qn, 0);
+ ncnt++;
+ }
+ }
+ if (ncnt <= 1)
+ {
+ queue_empty(q);
+ }
+ else
+ {
+ queue_empty(q);
+ queue_insertn(q, 0, qn.count - qnc, qn.elements + qnc);
+ }
+ queue_free(&qn);
+}
+
+void
+solver_addyumobsrules(Solver *solv)
+{
+ Pool *pool = solv->pool;
+ Repo *installed = solv->installed;
+ Id p, op, *opp;
+ Solvable *s;
+ Queue qo, qq, yumobsinfoq;
+ int i, j, k;
+ unsigned int now;
+
+ solv->yumobsrules = solv->nrules;
+ if (!installed || !solv->obsoletes)
+ {
+ solv->yumobsrules_end = solv->nrules;
+ return;
+ }
+ now = solv_timems(0);
+ queue_init(&qo);
+ FOR_REPO_SOLVABLES(installed, p, s)