Skip to content

Commit

Permalink
improve conda variant handling
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfv committed Jun 2, 2021
1 parent e2ed3f2 commit 316da14
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/conda.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ solv_vercmp_conda(const char *s1, const char *q1, const char *s2, const char *q2
return -1;
if (s1p - s1 > s2p - s2)
return 1;
r = s1p - s1 ? strncmp(s1, s2, s1p - s1) : 0;
r = (s1p - s1) ? strncmp(s1, s2, s1p - s1) : 0;
if (r)
return r;
}
Expand Down
104 changes: 89 additions & 15 deletions src/policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,11 @@ pool_buildflavorcmp(Pool *pool, Solvable *s1, Solvable *s2)
void
prune_to_best_version(Pool *pool, Queue *plist)
{
#ifdef ENABLE_CONDA
if (pool->disttype == DISTTYPE_CONDA)
return prune_to_best_version_conda(pool, plist);
#endif

int i, j, r;
Solvable *s, *best;

Expand Down Expand Up @@ -909,30 +914,16 @@ prune_to_best_version(Pool *pool, Queue *plist)
}

r = 0;
#ifdef ENABLE_CONDA
if (pool->disttype == DISTTYPE_CONDA)
r = pool_featurecountcmp(pool, best, s);
#endif
if (r == 0)
r = best->evr != s->evr ? pool_evrcmp(pool, best->evr, s->evr, EVRCMP_COMPARE) : 0;
#ifdef ENABLE_LINKED_PKGS
if (r == 0 && has_package_link(pool, s))
r = pool_link_evrcmp(pool, best, s);
#endif
#ifdef ENABLE_CONDA
if (pool->disttype == DISTTYPE_CONDA)
{
if (r == 0)
r = (best->repo ? best->repo->subpriority : 0) - (s->repo ? s->repo->subpriority : 0);
if (r == 0)
r = pool_buildversioncmp(pool, best, s);
if (r == 0)
r = pool_buildflavorcmp(pool, best, s);
}
#endif
if (r < 0)
best = s;
}

plist->elements[j++] = best - pool->solvables; /* finish last group */
plist->count = j;

Expand All @@ -947,6 +938,89 @@ prune_to_best_version(Pool *pool, Queue *plist)
}
}

#ifdef ENABLE_CONDA
/*
* prune_to_best_version_conda
*
* sort list of packages (given through plist) by name and evr
* return result through plist
*/
void
prune_to_best_version_conda(Pool *pool, Queue *plist)
{
int i, j, r;
Solvable *s, *best;

if (plist->count < 2) /* no need to prune for a single entry */
return;
POOL_DEBUG(SOLV_DEBUG_POLICY, "prune_to_best_version_conda %d\n", plist->count);

/* sort by name first, prefer installed */
solv_sort(plist->elements, plist->count, sizeof(Id), prune_to_best_version_sortcmp, pool);

/* now find best 'per name' */
best = 0;
for (i = j = 0; i < plist->count; i++)
{
s = pool->solvables + plist->elements[i];

POOL_DEBUG(SOLV_DEBUG_POLICY, "- %s [%d]%s\n",
pool_solvable2str(pool, s), plist->elements[i],
(pool->installed && s->repo == pool->installed) ? "I" : "");

if (!best) /* if no best yet, the current is best */
{
best = s;
continue;
}

/* name switch: finish group, re-init */
if (best->name != s->name) /* new name */
{
plist->elements[j++] = best - pool->solvables; /* move old best to front */
best = s; /* take current as new best */
continue;
}

r = 0;
r = pool_featurecountcmp(pool, best, s);
if (r == 0)
r = best->evr != s->evr ? pool_evrcmp(pool, best->evr, s->evr, EVRCMP_COMPARE) : 0;
if (r == 0)
r = (best->repo ? best->repo->subpriority : 0) - (s->repo ? s->repo->subpriority : 0);
if (r == 0)
r = pool_buildversioncmp(pool, best, s);
if (r == 0)
r = pool_buildflavorcmp(pool, best, s);
if (r < 0)
best = s;
}

Queue q;
queue_init(&q);
for (i = j = 0; i < plist->count; i++)
{
s = pool->solvables + plist->elements[i];
r = pool_featurecountcmp(pool, best, s);
if (r == 0)
r = best->evr != s->evr ? pool_evrcmp(pool, best->evr, s->evr, EVRCMP_COMPARE) : 0;
if (r == 0)
r = (best->repo ? best->repo->subpriority : 0) - (s->repo ? s->repo->subpriority : 0);
if (r == 0)
r = pool_buildversioncmp(pool, best, s);
if (r == 0)
queue_push(&q, s - pool->solvables);
}

for (i = 0; i < q.count; ++i)
{
plist->elements[i] = q.elements[i];
}

plist->count = q.count;
queue_free(&q);
}
#endif // ENABLE_CONDA

static int
sort_by_name_evr_sortcmp(const void *ap, const void *bp, void *dp)
Expand Down
3 changes: 3 additions & 0 deletions src/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ extern void pool_best_solvables(Pool *pool, Queue *plist, int flags);

/* internal, do not use */
extern void prune_to_best_version(Pool *pool, Queue *plist);
#ifdef ENABLE_CONDA
extern void prune_to_best_version_conda(Pool *pool, Queue *plist);
#endif
extern void policy_prefer_favored(Solver *solv, Queue *plist);


Expand Down
29 changes: 28 additions & 1 deletion src/solver.c
Original file line number Diff line number Diff line change
Expand Up @@ -3360,6 +3360,30 @@ setup_favormap(Solver *solv)
}
}

static void
setup_trackfeatures_favor(Solver *solv)
{
Pool *pool = solv->pool;
int idx, cnt;
Id p;

solv_free(solv->favormap);
solv->favormap = solv_calloc(pool->nsolvables, sizeof(Id));

idx = 0;
FOR_POOL_SOLVABLES(p)
{
Solvable *s = pool->solvables + p;
cnt = solvable_lookup_count(s, SOLVABLE_TRACK_FEATURES);
if (cnt != 0)
{
idx++;
solv->favormap[p] = -idx;
solv->havedisfavored = 1;
}
}
}

/*
*
* solve job queue
Expand Down Expand Up @@ -4022,7 +4046,10 @@ solver_solve(Solver *solv, Queue *job)
/* create favormap if we have favor jobs */
if (hasfavorjob)
setup_favormap(solv);

#ifdef ENABLE_CONDA
else
setup_trackfeatures_favor(solv);
#endif
/* now create infarch and dup rules */
if (!solv->noinfarchcheck)
solver_addinfarchrules(solv, &addedmap);
Expand Down

0 comments on commit 316da14

Please sign in to comment.