[Notes] [Git][BuildStream/buildstream][bschubert/non-recursive-sort] Make sorting dependencies non recursive



Title: GitLab

Benjamin Schubert pushed to branch bschubert/non-recursive-sort at BuildStream / buildstream

Commits:

2 changed files:

Changes:

  • buildstream/_loader/loadelement.py
    ... ... @@ -69,6 +69,7 @@ class LoadElement():
    69 69
             self.full_name = None  # The element full name (with associated junction)
    
    70 70
             self.deps = None       # The list of Dependency objects
    
    71 71
             self.node_id = next(self._counter)
    
    72
    +        self.has_sorted_dependencies = False  # Whether the element had his dependencies sorted already
    
    72 73
     
    
    73 74
             #
    
    74 75
             # Private members
    

  • buildstream/_loader/loader.py
    ... ... @@ -19,6 +19,7 @@
    19 19
     
    
    20 20
     import os
    
    21 21
     from functools import cmp_to_key
    
    22
    +from collections import deque
    
    22 23
     from collections.abc import Mapping
    
    23 24
     import tempfile
    
    24 25
     import shutil
    
    ... ... @@ -144,20 +145,12 @@ class Loader():
    144 145
             self._check_circular_deps(dummy_target)
    
    145 146
             profile_end(Topics.CIRCULAR_CHECK, profile_key)
    
    146 147
     
    
    147
    -        ret = []
    
    148
    -        #
    
    149
    -        # Sort direct dependencies of elements by their dependency ordering
    
    150
    -        #
    
    151
    -        for element in target_elements:
    
    152
    -            loader = element._loader
    
    153
    -            profile_start(Topics.SORT_DEPENDENCIES, element.name)
    
    154
    -            loader._sort_dependencies(element)
    
    155
    -            profile_end(Topics.SORT_DEPENDENCIES, element.name)
    
    156
    -            # Finally, wrap what we have into LoadElements and return the target
    
    157
    -            #
    
    158
    -            ret.append(loader._collect_element(element))
    
    148
    +        self._sort_dependencies(target_elements)
    
    159 149
     
    
    160
    -        return ret
    
    150
    +        return [
    
    151
    +            element._loader._collect_element(element)
    
    152
    +            for element in target_elements
    
    153
    +        ]
    
    161 154
     
    
    162 155
         # cleanup():
    
    163 156
         #
    
    ... ... @@ -337,18 +330,9 @@ class Loader():
    337 330
         # sorts throughout the build process.
    
    338 331
         #
    
    339 332
         # Args:
    
    340
    -    #    element (LoadElement): The element to sort
    
    333
    +    #    element (list[LoadElement]): The elements to sort
    
    341 334
         #
    
    342
    -    def _sort_dependencies(self, element, visited=None):
    
    343
    -        if visited is None:
    
    344
    -            visited = set()
    
    345
    -
    
    346
    -        if element in visited:
    
    347
    -            return
    
    348
    -
    
    349
    -        for dep in element.dependencies:
    
    350
    -            dep.element._loader._sort_dependencies(dep.element, visited=visited)
    
    351
    -
    
    335
    +    def _sort_dependencies(self, elements):
    
    352 336
             def dependency_cmp(dep_a, dep_b):
    
    353 337
                 element_a = dep_a.element
    
    354 338
                 element_b = dep_b.element
    
    ... ... @@ -388,12 +372,25 @@ class Loader():
    388 372
                 # This wont ever happen
    
    389 373
                 return 0
    
    390 374
     
    
    391
    -        # Now dependency sort, we ensure that if any direct dependency
    
    392
    -        # directly or indirectly depends on another direct dependency,
    
    393
    -        # it is found later in the list.
    
    394
    -        element.dependencies.sort(key=cmp_to_key(dependency_cmp))
    
    375
    +        elements_to_treat = deque(elements)
    
    376
    +        sort_key = cmp_to_key(dependency_cmp)
    
    377
    +
    
    378
    +        profile_start(Topics.SORT_DEPENDENCIES, "_".join(e.name.replace(os.sep, '-') for e in elements))
    
    379
    +        while elements_to_treat:
    
    380
    +            elem = elements_to_treat.pop()
    
    381
    +
    
    382
    +            if elem.has_sorted_dependencies:
    
    383
    +                continue
    
    384
    +
    
    385
    +            elem.dependencies.sort(key=sort_key)
    
    386
    +            elements_to_treat.extend(
    
    387
    +                dep.element
    
    388
    +                for dep in elem.dependencies
    
    389
    +                if not dep.element.has_sorted_dependencies
    
    390
    +            )
    
    391
    +            elem.has_sorted_dependencies = True
    
    395 392
     
    
    396
    -        visited.add(element)
    
    393
    +        profile_end(Topics.SORT_DEPENDENCIES, "_".join(e.name.replace(os.sep, '-') for e in elements))
    
    397 394
     
    
    398 395
         # _collect_element()
    
    399 396
         #
    



  • [Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]