diff options
author | Jürg Billeter <j@bitron.ch> | 2019-02-24 16:52:15 +0100 |
---|---|---|
committer | Jürg Billeter <j@bitron.ch> | 2019-02-26 12:12:46 +0100 |
commit | f7bc89ea3b31f9f46f4e3ac67071d0dbd37094ac (patch) | |
tree | ac5c08ad6698afa0d8dcb4f10b06b455390e5149 | |
parent | f6176579f122d370c4ecaba0df1512cea079e0f0 (diff) | |
download | buildstream-f7bc89ea3b31f9f46f4e3ac67071d0dbd37094ac.tar.gz |
_casbaseddirectory.py: Use lazy instantiation for subdirectories
This avoids creation of directory objects for the whole tree, if only a
part of the tree is used.
-rw-r--r-- | buildstream/storage/_casbaseddirectory.py | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/buildstream/storage/_casbaseddirectory.py b/buildstream/storage/_casbaseddirectory.py index aef49c4d9..26d72efdc 100644 --- a/buildstream/storage/_casbaseddirectory.py +++ b/buildstream/storage/_casbaseddirectory.py @@ -48,6 +48,13 @@ class IndexEntry(): self.buildstream_object = buildstream_object self.modified = modified + def get_directory(self, parent): + if not self.buildstream_object: + self.buildstream_object = CasBasedDirectory(parent.cas_cache, ref=self.pb_object.digest, + parent=parent, filename=self.pb_object.name) + + return self.buildstream_object + class ResolutionException(VirtualDirectoryError): """ Superclass of all exceptions that can be raised by @@ -119,10 +126,7 @@ class CasBasedDirectory(Directory): if self._directory_read: return for entry in self.pb2_directory.directories: - buildStreamDirectory = CasBasedDirectory(self.cas_cache, ref=entry.digest, - parent=self, filename=entry.name) - self.index[entry.name] = IndexEntry(entry, _FileType.DIRECTORY, - buildstream_object=buildStreamDirectory) + self.index[entry.name] = IndexEntry(entry, _FileType.DIRECTORY) for entry in self.pb2_directory.files: self.index[entry.name] = IndexEntry(entry, _FileType.REGULAR_FILE) for entry in self.pb2_directory.symlinks: @@ -152,7 +156,9 @@ class CasBasedDirectory(Directory): """ for entry in self.pb2_directory.directories: - self.index[entry.name].buildstream_object._recalculate_recursing_down(entry) + subdir = self.index[entry.name].buildstream_object + if subdir: + subdir._recalculate_recursing_down(entry) if parent: self.ref = self.cas_cache.add_object(digest=parent.digest, buffer=self.pb2_directory.SerializeToString()) @@ -253,7 +259,7 @@ class CasBasedDirectory(Directory): if subdirectory_spec[0] in self.index: entry = self.index[subdirectory_spec[0]] if entry.type == _FileType.DIRECTORY: - subdir = entry.buildstream_object + subdir = entry.get_directory(self) return subdir.descend(subdirectory_spec[1:], create) else: error = "Cannot descend into {}, which is a '{}' in the directory {}" @@ -284,7 +290,8 @@ class CasBasedDirectory(Directory): elif existing_entry.type == _FileType.DIRECTORY: # If 'name' maps to a DirectoryNode, then there must be an entry in index # pointing to another Directory. - if self.index[name].buildstream_object.is_empty(): + subdir = existing_entry.get_directory(self) + if subdir.is_empty(): self.delete_entry(name) fileListResult.overwritten.append(relative_pathname) return True @@ -536,7 +543,7 @@ class CasBasedDirectory(Directory): # Marks all entries in this directory and all child directories as unmodified. for i in self.index.values(): i.modified = False - if i.type == _FileType.DIRECTORY: + if i.type == _FileType.DIRECTORY and i.buildstream_object: i.buildstream_object._mark_directory_unmodified() def _mark_entry_unmodified(self, name): @@ -573,7 +580,7 @@ class CasBasedDirectory(Directory): if component not in directory.index: return None if directory.index[component].type == _FileType.DIRECTORY: - directory = directory.index[component].buildstream_object + directory = directory.index[component].get_directory(self) else: return None return directory.index.get(path_components[-1], None) @@ -608,7 +615,8 @@ class CasBasedDirectory(Directory): yield os.path.join(relpath, k) for (k, v) in sorted(directory_list): - yield from v.buildstream_object.list_relative_paths(relpath=os.path.join(relpath, k)) + subdir = v.get_directory(self) + yield from subdir.list_relative_paths(relpath=os.path.join(relpath, k)) def recalculate_hash(self): """ Recalcuates the hash for this directory and store the results in @@ -623,7 +631,8 @@ class CasBasedDirectory(Directory): total = len(self.pb2_directory.SerializeToString()) for i in self.index.values(): if i.type == _FileType.DIRECTORY: - total += i.buildstream_object.get_size() + subdir = i.get_directory(self) + total += subdir.get_size() elif i.type == _FileType.REGULAR_FILE: src_name = self.cas_cache.objpath(i.pb_object.digest) filesize = os.stat(src_name).st_size |