summaryrefslogtreecommitdiff
path: root/buildstream/_loader.py
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2017-02-25 19:13:40 +0900
committerTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2017-02-25 19:13:40 +0900
commitdaea7b623fe7d8287f92ffe9f50ba530579e6302 (patch)
treea6edf57b5c7239ae613b4872ac5eab2ce7a000f1 /buildstream/_loader.py
parenta030ad1073155e8661d6a2e2903ee275dad327be (diff)
downloadbuildstream-daea7b623fe7d8287f92ffe9f50ba530579e6302.tar.gz
_loader.py: Fix / optimize dependency sorting.
This was working but very expensive, now we cache a flat dictionary of each element's dependencies once in order to query deep dependencies for the sort, this memory will anyway be let go after the load process completes.
Diffstat (limited to 'buildstream/_loader.py')
-rwxr-xr-xbuildstream/_loader.py34
1 files changed, 16 insertions, 18 deletions
diff --git a/buildstream/_loader.py b/buildstream/_loader.py
index 8e5b31dda..98613aa1c 100755
--- a/buildstream/_loader.py
+++ b/buildstream/_loader.py
@@ -163,6 +163,7 @@ class LoadElement():
# Dependency objects after resolving variants
self.variant_name = None
self.deps = []
+ self.dep_cache = None
# Base dependencies
self.base_deps = extract_depends_from_node(self.name, self.data)
@@ -197,31 +198,28 @@ class LoadElement():
# or indirectly. This does NOT follow variants and is only
# useful after variants are resolved.
#
- def depends(self, other, visited=None):
- if visited is None:
- visited = {}
+ def depends(self, other):
- if visited.get(self.name) is not None:
- return False
+ self.ensure_depends_cache()
+ return self.dep_cache.get(other.name) is not None
- # 'self' depends on 'other' if 'other' is
- # found in any of 'self's dependencies
- #
- for dep in self.deps:
+ def ensure_depends_cache(self):
- elt = self.elements[dep.name]
+ if self.dep_cache:
+ return
- # On of our dependencies is 'other'
- if elt == other:
- return True
+ self.dep_cache = {}
+ for dep in self.deps:
+ elt = self.elements[dep.name]
- # Check if an indirect dependency depends on 'other'
- elif elt.depends(other, visited=visited):
- return True
+ # Ensure the cache of the element we depend on
+ elt.ensure_depends_cache()
- visited[dep.name] = True
+ # We depend on this element
+ self.dep_cache[dep.name] = True
- return False
+ # And we depend on everything this element depends on
+ self.dep_cache.update(elt.dep_cache)
# Fetch a Variant by name
#