summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Schubert <ben.c.schubert@gmail.com>2019-02-12 17:15:27 +0000
committerBenjamin Schubert <ben.c.schubert@gmail.com>2019-02-12 17:26:48 +0000
commit0422739553609665d5cc7fc26a4aebdadb4dfeea (patch)
tree5ac8d20c813cbf1f54dbf297d6dea78eb059a507
parent022a59f0919333cb98cf5f43f1969191f6805eb6 (diff)
downloadbuildstream-bschubert/non-recursive-sort.tar.gz
Make sorting dependencies non recursivebschubert/non-recursive-sort
-rw-r--r--buildstream/_loader/loadelement.py1
-rw-r--r--buildstream/_loader/loader.py55
2 files changed, 27 insertions, 29 deletions
diff --git a/buildstream/_loader/loadelement.py b/buildstream/_loader/loadelement.py
index 17154ee64..9e47c062e 100644
--- a/buildstream/_loader/loadelement.py
+++ b/buildstream/_loader/loadelement.py
@@ -69,6 +69,7 @@ class LoadElement():
self.full_name = None # The element full name (with associated junction)
self.deps = None # The list of Dependency objects
self.node_id = next(self._counter)
+ self.has_sorted_dependencies = False # Whether the element had his dependencies sorted already
#
# Private members
diff --git a/buildstream/_loader/loader.py b/buildstream/_loader/loader.py
index fc946d50b..75dc9ab15 100644
--- a/buildstream/_loader/loader.py
+++ b/buildstream/_loader/loader.py
@@ -19,6 +19,7 @@
import os
from functools import cmp_to_key
+from collections import deque
from collections.abc import Mapping
import tempfile
import shutil
@@ -144,20 +145,12 @@ class Loader():
self._check_circular_deps(dummy_target)
profile_end(Topics.CIRCULAR_CHECK, profile_key)
- ret = []
- #
- # Sort direct dependencies of elements by their dependency ordering
- #
- for element in target_elements:
- loader = element._loader
- profile_start(Topics.SORT_DEPENDENCIES, element.name)
- loader._sort_dependencies(element)
- profile_end(Topics.SORT_DEPENDENCIES, element.name)
- # Finally, wrap what we have into LoadElements and return the target
- #
- ret.append(loader._collect_element(element))
+ self._sort_dependencies(target_elements)
- return ret
+ return [
+ element._loader._collect_element(element)
+ for element in target_elements
+ ]
# cleanup():
#
@@ -337,18 +330,9 @@ class Loader():
# sorts throughout the build process.
#
# Args:
- # element (LoadElement): The element to sort
+ # element (list[LoadElement]): The elements to sort
#
- def _sort_dependencies(self, element, visited=None):
- if visited is None:
- visited = set()
-
- if element in visited:
- return
-
- for dep in element.dependencies:
- dep.element._loader._sort_dependencies(dep.element, visited=visited)
-
+ def _sort_dependencies(self, elements):
def dependency_cmp(dep_a, dep_b):
element_a = dep_a.element
element_b = dep_b.element
@@ -388,12 +372,25 @@ class Loader():
# This wont ever happen
return 0
- # Now dependency sort, we ensure that if any direct dependency
- # directly or indirectly depends on another direct dependency,
- # it is found later in the list.
- element.dependencies.sort(key=cmp_to_key(dependency_cmp))
+ elements_to_treat = deque(elements)
+ sort_key = cmp_to_key(dependency_cmp)
+
+ profile_start(Topics.SORT_DEPENDENCIES, "_".join(e.name.replace(os.sep, '-') for e in elements))
+ while elements_to_treat:
+ elem = elements_to_treat.pop()
+
+ if elem.has_sorted_dependencies:
+ continue
+
+ elem.dependencies.sort(key=sort_key)
+ elements_to_treat.extend(
+ dep.element
+ for dep in elem.dependencies
+ if not dep.element.has_sorted_dependencies
+ )
+ elem.has_sorted_dependencies = True
- visited.add(element)
+ profile_end(Topics.SORT_DEPENDENCIES, "_".join(e.name.replace(os.sep, '-') for e in elements))
# _collect_element()
#