depgraph: optimize slot conflict backtrack order
authorZac Medico <zmedico@gentoo.org>
Tue, 19 Jun 2012 21:27:11 +0000 (14:27 -0700)
committerZac Medico <zmedico@gentoo.org>
Tue, 19 Jun 2012 21:27:11 +0000 (14:27 -0700)
pym/_emerge/depgraph.py
pym/_emerge/resolver/backtracking.py

index 071d05863489bdaeeb3b89ad6eee98feab462f68..291080ac7e3392dea0cb60d87cd562e984587993 100644 (file)
@@ -366,7 +366,11 @@ class _dynamic_depgraph_config(object):
                # This use used to check if we have accounted for blockers
                # relevant to a package.
                self._traversed_pkg_deps = set()
-               self._slot_collision_info = {}
+               # This should be ordered such that the backtracker will
+               # attempt to solve conflicts which occurred earlier first,
+               # since an earlier conflict can be the cause of a conflict
+               # which occurs later.
+               self._slot_collision_info = OrderedDict()
                # Slot collision nodes are not allowed to block other packages since
                # blocker validation is only able to account for one package per slot.
                self._slot_collision_nodes = set()
@@ -911,7 +915,7 @@ class depgraph(object):
                to_be_masked = backtrack_data[-1][0]
 
                self._dynamic_config._backtrack_infos.setdefault(
-                       "slot conflict", []).extend(backtrack_data)
+                       "slot conflict", []).append(backtrack_data)
                self._dynamic_config._need_restart = True
                if debug:
                        msg = []
index f2857b0f5762db2bbf0859e9a79744312dcc9b96..2f8b6d0b6d570645e8cb8117f4e93ee07a44fadb 100644 (file)
@@ -131,6 +131,14 @@ class Backtracker(object):
 
                return True
 
+       def _feedback_slot_conflicts(self, conflicts_data):
+               # This should be ordered such that the backtracker will
+               # attempt to solve conflicts which occurred earlier first,
+               # since an earlier conflict can be the cause of a conflict
+               # which occurs later.
+               for slot_data in reversed(conflicts_data):
+                       self._feedback_slot_conflict(slot_data)
+
        def _feedback_slot_conflict(self, conflict_data):
                for pkg, parent_atoms in conflict_data:
                        new_node = copy.deepcopy(self._current_node)
@@ -196,7 +204,7 @@ class Backtracker(object):
 
                #There is at most one of the following types of conflicts for a given restart.
                if "slot conflict" in infos:
-                       self._feedback_slot_conflict(infos["slot conflict"])
+                       self._feedback_slot_conflicts(infos["slot conflict"])
                elif "missing dependency" in infos:
                        self._feedback_missing_dep(infos["missing dependency"])