On Thu, 27 Feb 2014 20:08:49 +0100
Sebastian Luther wrote:
> This function allows emerge to solve more slot conflicts without
> backtracking.
>
> It does this by creating more conflicts for packages with built slot
> operator dependencies. This gives more freedom to
> depgraph._solve_non_slot_operator_slot_conflicts, which is then able
> to solve conflicts it wouldn't have otherwise.
> ---
Nice patch!
For haskell packages it makes huge difference.
My typical workflow is:
- bump some package foo and it's subslot
- emerge -1 foo -j9
- see what will get rebuilt/broken by subslot rebuild
If package would trigger 500 rebuilds portage had no chance
to find a solution with backtracks. Now sometimes it does.
Thanks!
> pym/_emerge/depgraph.py| 483
> +++--
> pym/_emerge/resolver/output.py | 5 +-
> 2 files changed, 415 insertions(+), 73 deletions(-)
>
> diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
> index 835bd6b..970a9c7 100644
> --- a/pym/_emerge/depgraph.py
> +++ b/pym/_emerge/depgraph.py
> @@ -427,6 +427,12 @@ class _dynamic_depgraph_config(object):
> # Track missed updates caused by solved conflicts.
> self._conflict_missed_update = collections.defaultdict(dict)
>
> + # Rebuilds caused by slot conflicts.
> + self._slot_conflict_rebuilds = {}
> + # Rebuilds caused by missed slot operator updates or
> + # slot conflicts.
> + self._forced_rebuilds = None
> +
> for myroot in depgraph._frozen_config.trees:
> self.sets[myroot] = _depgraph_sets()
> vardb =
> depgraph._frozen_config.trees[myroot]["vartree"].dbapi
> @@ -614,6 +620,9 @@ class depgraph(object):
> Fill self._forced_rebuilds with packages that cause rebuilds.
> """
>
> + if self._dynamic_config._forced_rebuilds is not None:
> + return
> +
> debug = "--debug" in self._frozen_config.myopts
>
> # Get all atoms that might have caused a forced rebuild.
> @@ -687,19 +696,23 @@ class depgraph(object):
> writemsg_level("\n\n",
> level=logging.DEBUG, noiselevel=-1)
>
> - self._forced_rebuilds = forced_rebuilds
> + for child, parents in
> self._dynamic_config._slot_conflict_rebuilds.items():
> + forced_rebuilds.setdefault(child.root,
> {}).setdefault(child, set()).update(parents)
> +
> + self._dynamic_config._forced_rebuilds = forced_rebuilds
>
> def _show_abi_rebuild_info(self):
>
> - if not self._forced_rebuilds:
> + forced_rebuilds = self._dynamic_config._forced_rebuilds
> + if not forced_rebuilds:
> return
>
> writemsg_stdout("\nThe following packages are causing
> rebuilds:\n\n", noiselevel=-1)
>
> - for root in self._forced_rebuilds:
> - for child in self._forced_rebuilds[root]:
> + for root in forced_rebuilds:
> + for child in forced_rebuilds[root]:
> writemsg_stdout(" %s causes rebuilds for:\n" %
> (child,), noiselevel=-1)
> - for parent in
> self._forced_rebuilds[root][child]:
> + for parent in forced_rebuilds[root][child]:
> writemsg_stdout("%s\n" % (parent,),
> noiselevel=-1)
>
> def _show_ignored_binaries(self):
> @@ -968,16 +981,16 @@ class depgraph(object):
> writemsg(line + '\n', noiselevel=-1)
> writemsg('\n', noiselevel=-1)
>
> - def _solve_non_slot_operator_slot_conflicts(self):
> +
> + def _extend_slot_operator_conflicts(self):
> """
> - This function solves slot conflicts which can
> - be solved by simply choosing one of the conflicting
> - and removing all the other ones.
> - It is able to solve somewhat more complex cases where
> - conflicts can only be solved simultaniously.
> + This function searches for packages that cause
> + slot conflicts by dependening on conflict packages
> + with built slot operator deps. If such a package
> + is found an alternative package is pulled in with
> + the hope that the alternative package would not
> + cuase the slot conflict.
> """
> - debug = "--debug" in self._frozen_config.myopts
> -
> # List all conflicts. Ignore those that involve slot operator
> rebuilds
> # as the logic there needs special slot conflict behavior which
> isn't
> # provided by this function.
> @@ -990,9 +1003,133 @@ class depgraph(object):
> if not conflicts