From 0346e845fa3ab6a97197aebfa6d8049e9ced83e2 Mon Sep 17 00:00:00 2001 From: kotborealis Date: Wed, 12 Aug 2026 17:20:21 +0300 Subject: [PATCH 1/3] _artifact: Remove unused output size traversal Artifact.cache() already stores the collected directory digest and never uses the recursive size calculation that follows it. Remove the dead accumulator and _get_size() call so artifact creation does not walk the output tree a second time. --- src/buildstream/_artifact.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/buildstream/_artifact.py b/src/buildstream/_artifact.py index 075be8fe3..fc196bcff 100644 --- a/src/buildstream/_artifact.py +++ b/src/buildstream/_artifact.py @@ -220,7 +220,6 @@ def cache( context = self._context element = self._element - size = 0 filesvdir = None buildtreevdir = None @@ -247,7 +246,6 @@ def cache( filesvdir = CasBasedDirectory(cas_cache=self._cas) filesvdir._import_files_internal(collectvdir, properties=properties, collect_result=False) artifact.files.CopyFrom(filesvdir._get_digest()) - size += filesvdir._get_size() with tempfile.TemporaryDirectory() as tmpdir: files_to_capture = [] From 0f7107ff51181f93fa1ba34d4d121711e6b6cfff Mon Sep 17 00:00:00 2001 From: kotborealis Date: Wed, 12 Aug 2026 17:20:22 +0300 Subject: [PATCH 2/3] _cas: Avoid duplicate directory tree fetch fetch_directory() has already fetched the directory protos with FetchTree before enumerating required blobs. Tell required_blobs_for_directory() to reuse those local protos instead of issuing another FetchTree request, reducing remote CAS round trips. --- src/buildstream/_cas/cascache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/buildstream/_cas/cascache.py b/src/buildstream/_cas/cascache.py index 61a84b694..0db18dd4a 100644 --- a/src/buildstream/_cas/cascache.py +++ b/src/buildstream/_cas/cascache.py @@ -286,7 +286,7 @@ def fetch_directory(self, remote, dir_digest): "Failed to fetch directory tree {}: {}: {}".format(dir_digest.hash, e.code().name, e.details()) ) from e - required_blobs = self.required_blobs_for_directory(dir_digest) + required_blobs = self.required_blobs_for_directory(dir_digest, _fetch_tree=False) self.fetch_blobs(remote, required_blobs) # pull_tree(): From dc65f9c3a328e46649c52baca634dc1f10bdaa54 Mon Sep 17 00:00:00 2001 From: kotborealis Date: Wed, 12 Aug 2026 17:20:22 +0300 Subject: [PATCH 3/3] element: Reuse build dependencies for cache keys Weak and strict cache keys both consume the same build dependency list. Materialize the generator once and reuse it so cache-key updates do not traverse the dependency graph twice while preserving the existing key inputs and ordering. --- src/buildstream/element.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/buildstream/element.py b/src/buildstream/element.py index 209b9e9a9..e7685448d 100644 --- a/src/buildstream/element.py +++ b/src/buildstream/element.py @@ -3337,6 +3337,8 @@ def __update_cache_keys(self): # This code can be run multiple times until the strict key can be calculated, # so let's ensure we only ever calculate the weak key once, even though we need # to resolve it before we can resolve the strict key. + build_dependencies = list(self._dependencies(_Scope.BUILD)) + if self.__weak_cache_key is None: # Weak cache key includes names of direct build dependencies # so as to only trigger rebuilds when the shape of the @@ -3353,14 +3355,14 @@ def __update_cache_keys(self): if self.BST_STRICT_REBUILD or e in self.__strict_dependencies else [e.project_name, e.name] ) - for e in self._dependencies(_Scope.BUILD) + for e in build_dependencies ] self.__weak_cache_key = self._calculate_cache_key(dependencies) context = self._get_context() # Calculate the strict cache key - dependencies = [[e.project_name, e.name, e.__strict_cache_key] for e in self._dependencies(_Scope.BUILD)] + dependencies = [[e.project_name, e.name, e.__strict_cache_key] for e in build_dependencies] self.__strict_cache_key = self._calculate_cache_key(dependencies, self.__weak_cache_key) if self.__strict_cache_key is None: