Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement strict repo priority #459

Merged
merged 2 commits into from
Oct 15, 2021
Merged

Conversation

adriendelsalle
Copy link
Contributor

Description

Implement strict repo priority
Add specific rule
Add solver flag
Add problem message/debug

Closes #458

@@ -3028,8 +3034,8 @@ solver_ruleclass(Solver *solv, Id rid)
return SOLVER_RULE_CHOICE;
if (rid >= solv->recommendsrules && rid < solv->recommendsrules_end)
return SOLVER_RULE_RECOMMENDS;
if (rid >= solv->blackrules && rid < solv->blackrules_end)
return SOLVER_RULE_BLACK;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: the block was duplicate from L3025

@adriendelsalle
Copy link
Contributor Author

cc @wolfv

src/rules.c Outdated
{
s = pool->solvables + sid;
int max_prio = 0;
FOR_PROVIDES(p, pp, s->name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could cache the max prio here since it's the same for each s->name id. @mlschroe do you have a suggestion how to make a map? maybe we can allocate an array with the size of pool->ss.nstrings? Or is there a better way?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E.g.

int* cache = solv_calloc(pool->ss.nstrings, sizeof(int));

then we can use that null-initialized buffer to cache values:

if (cache[s->name] == 0)
{
For provides ...

}
else
{
max_prio = cache[s->name] - 1;
}
...

@mlschroe
Copy link
Member

mlschroe commented Jul 9, 2021

I would do it a bit different:

  1. pass the "addedmap" to the function. It contains a map of all solvables relevant for the job. This limits the amount of work we do.
  2. create a copy of the map
  3. change the code so that it runs over the names, not the solvables. Thus we can reuse the max prio instead of calculating it again:
map_init_clone(&todo, addedmap);
FOR_POOL_SOLVABLES(p)
  {
    if (!MAPTST(&todo, p))
      continue;
    s = pool->solvables + p;
    max_prio = s->repo->priority;
    FOR_PROVIDES(p2, pp2, s->name)
      {
        Solvable *s2 = pool->solvables + p2;
        if (s->name != s2->name)
          continue;
        if (s2->repo->priority > max_prio)
          max_prio = s2->repo->priority;
      }
    FOR_PROVIDES(p2, pp2, s->name)
      {
        Solvable *s2 = pool->solvables + p2;
        if (s->name != s2->name || !MAPTST(&todo, p2))
          continue;
        MAPCLR(&todo, p2);
        if (s2->repo < max_prio)
          solver_addrule(solv, -p2, 0, 0);
      }
  }

@mlschroe
Copy link
Member

mlschroe commented Jul 9, 2021

(The code above is completely untested)

src/rules.c Outdated Show resolved Hide resolved
FOR_PROVIDES(p2, pp2, s->name)
{
Solvable *s2 = pool->solvables + p2;
if (s->name != s2->name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this probably never happens in the case of conda repodata, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's good to do anyway as the strict repo prio code will probably be used by other distros as well.

src/rules.c Outdated
Solvable *s2 = pool->solvables + p2;
if (s->name != s2->name)
{
MAPCLR(&priomap, p2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why mapclr here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, that's wrong. you mustn't clear the bits in the first loop, as the second loop also does a MAPTST.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wait, it only clears if the names are different. It's still wrong, though ;-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I think I got it, from conda packages names of providers are always the same so I take a wrong shortcut to clear them if names differ.

In the case where s->name != s2->name we don't clear s2 but just continue to not prevent to add rules for s2->name later right?

@Conan-Kudo
Copy link
Member

I'm not sure "strict repo priority" is the correct wording for this behavior. This describes as "weak repo priority" to me, since this explicitly makes it so higher NVRs in another repo still wins (priorities normally make it so lower NVRs win anyway, at least in DNF and Zypper).

@mlschroe
Copy link
Member

mlschroe commented Aug 7, 2021

The code doesn't check the version/release at all, so I don't understand your comment.

@Conan-Kudo
Copy link
Member

I was mostly going off #458.

@adriendelsalle
Copy link
Contributor Author

adriendelsalle commented Aug 9, 2021

@mlschroe I updated that PR, if you have opportunity to take a look it would be great :)

add specific rule
add solver flag
add problem message/debug
it would prevent those solvables for being excluded by strict channel priority
@wolfv
Copy link
Contributor

wolfv commented Sep 7, 2021

@mlschroe we've been using this in mamba for a while and seems fine! Any objection to merging it?

@SylvainCorlay
Copy link
Contributor

+1 on getting this in. This appears to be fixing all the channel priority issues we've had with earlier versions.

@mlschroe mlschroe merged commit aa7dcd9 into openSUSE:master Oct 15, 2021
@183amir
Copy link

183amir commented Oct 15, 2021

I am not getting clear error messages on conflicts with mamba and strict channel priority. Is there a way to get better error messages? Please see: mamba-org/mamba#1217

@adriendelsalle adriendelsalle deleted the strict-prio branch October 15, 2021 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

How to implement 'strict channel priority'?
6 participants