summaryrefslogtreecommitdiff
path: root/src/buildtool/execution_api/local/local_storage.cpp
diff options
context:
space:
mode:
authorOliver Reiche <oliver.reiche@huawei.com>2022-07-07 17:28:29 +0200
committerSascha Roloff <sascha.roloff@huawei.com>2022-08-05 14:41:31 +0200
commitdaca274041e31636f08927b0cebc56fd33c7bbdf (patch)
treed6b2c838d92abf7b4a4e98557359edf68fb84bcc /src/buildtool/execution_api/local/local_storage.cpp
parent13fd883b8cfa9531523f3113b32794f803c1176a (diff)
downloadjustbuild-daca274041e31636f08927b0cebc56fd33c7bbdf.tar.gz
LocalExecution: Use Git tree format
- LocalStorage Add tree CAS and support reading Git trees - LocalAction: Create Git tree for output directory - LocalApi: Support availability and upload of Git trees - LocalStorage: Support dumping tree to stream in native mode
Diffstat (limited to 'src/buildtool/execution_api/local/local_storage.cpp')
-rw-r--r--src/buildtool/execution_api/local/local_storage.cpp113
1 files changed, 88 insertions, 25 deletions
diff --git a/src/buildtool/execution_api/local/local_storage.cpp b/src/buildtool/execution_api/local/local_storage.cpp
index 5e4115df..e6d9571c 100644
--- a/src/buildtool/execution_api/local/local_storage.cpp
+++ b/src/buildtool/execution_api/local/local_storage.cpp
@@ -17,15 +17,46 @@ namespace {
return std::nullopt;
}
+[[nodiscard]] auto ReadGitTree(
+ gsl::not_null<LocalStorage const*> const& storage,
+ bazel_re::Digest const& digest) noexcept
+ -> std::optional<GitCAS::tree_entries_t> {
+ if (auto const path = storage->TreePath(digest)) {
+ if (auto const content = FileSystemManager::ReadFile(*path)) {
+ return GitCAS::ReadTreeData(
+ *content,
+ HashFunction::ComputeTreeHash(*content).Bytes(),
+ /*is_hex_id=*/false);
+ }
+ }
+ Logger::Log(LogLevel::Error, "Tree {} not found in CAS", digest.hash());
+ return std::nullopt;
+}
+
+[[nodiscard]] auto DumpToStream(gsl::not_null<FILE*> const& stream,
+ std::optional<std::string> const& data) noexcept
+ -> bool {
+ if (data) {
+ std::fwrite(data->data(), 1, data->size(), stream);
+ return true;
+ }
+ return false;
+}
+
[[nodiscard]] auto TreeToStream(
gsl::not_null<LocalStorage const*> const& storage,
bazel_re::Digest const& tree_digest,
gsl::not_null<FILE*> const& stream) noexcept -> bool {
- if (auto dir = ReadDirectory(storage, tree_digest)) {
- if (auto data = BazelMsgFactory::DirectoryToString(*dir)) {
- auto const& str = *data;
- std::fwrite(str.data(), 1, str.size(), stream);
- return true;
+ if (Compatibility::IsCompatible()) {
+ if (auto dir = ReadDirectory(storage, tree_digest)) {
+ return DumpToStream(stream,
+ BazelMsgFactory::DirectoryToString(*dir));
+ }
+ }
+ else {
+ if (auto entries = ReadGitTree(storage, tree_digest)) {
+ return DumpToStream(stream,
+ BazelMsgFactory::GitTreeToString(*entries));
}
}
return false;
@@ -36,8 +67,13 @@ namespace {
Artifact::ObjectInfo const& blob_info,
gsl::not_null<FILE*> const& stream) noexcept -> bool {
constexpr std::size_t kChunkSize{512};
- if (auto const path = storage->BlobPath(
- blob_info.digest, IsExecutableObject(blob_info.type))) {
+ auto path =
+ storage->BlobPath(blob_info.digest, IsExecutableObject(blob_info.type));
+ if (not path and not Compatibility::IsCompatible()) {
+ // in native mode, lookup object in tree cas to dump tree as blob
+ path = storage->TreePath(blob_info.digest);
+ }
+ if (path) {
std::string data(kChunkSize, '\0');
if (gsl::owner<FILE*> in = std::fopen(path->c_str(), "rb")) {
while (auto size = std::fread(data.data(), 1, kChunkSize, in)) {
@@ -103,26 +139,53 @@ auto LocalStorage::ReadObjectInfosRecursively(
}
// fallback read from CAS and cache it in in-memory tree map
- if (auto dir = ReadDirectory(this, digest)) {
- auto tree = tree_map_ ? std::make_optional(tree_map_->CreateTree())
- : std::nullopt;
- return BazelMsgFactory::ReadObjectInfosFromDirectory(
- *dir,
- [this, &store_info, &parent, &tree](auto path, auto info) {
- return (not tree or tree->AddInfo(path, info)) and
- (IsTreeObject(info.type)
- ? ReadObjectInfosRecursively(
- store_info, parent / path, info.digest)
- : store_info(parent / path, info));
- }) and
- (not tree_map_ or tree_map_->AddTree(digest, std::move(*tree)));
+ if (Compatibility::IsCompatible()) {
+ if (auto dir = ReadDirectory(this, digest)) {
+ auto tree = tree_map_ ? std::make_optional(tree_map_->CreateTree())
+ : std::nullopt;
+ return BazelMsgFactory::ReadObjectInfosFromDirectory(
+ *dir,
+ [this, &store_info, &parent, &tree](auto path,
+ auto info) {
+ return (not tree or tree->AddInfo(path, info)) and
+ (IsTreeObject(info.type)
+ ? ReadObjectInfosRecursively(
+ store_info,
+ parent / path,
+ info.digest)
+ : store_info(parent / path, info));
+ }) and
+ (not tree_map_ or
+ tree_map_->AddTree(digest, std::move(*tree)));
+ }
+ }
+ else {
+ if (auto entries = ReadGitTree(this, digest)) {
+ auto tree = tree_map_ ? std::make_optional(tree_map_->CreateTree())
+ : std::nullopt;
+ return BazelMsgFactory::ReadObjectInfosFromGitTree(
+ *entries,
+ [this, &store_info, &parent, &tree](auto path,
+ auto info) {
+ return (not tree or tree->AddInfo(path, info)) and
+ (IsTreeObject(info.type)
+ ? ReadObjectInfosRecursively(
+ store_info,
+ parent / path,
+ info.digest)
+ : store_info(parent / path, info));
+ }) and
+ (not tree_map_ or
+ tree_map_->AddTree(digest, std::move(*tree)));
+ }
}
return false;
}
-auto LocalStorage::DumpToStream(
- Artifact::ObjectInfo const& info,
- gsl::not_null<FILE*> const& stream) const noexcept -> bool {
- return IsTreeObject(info.type) ? TreeToStream(this, info.digest, stream)
- : BlobToStream(this, info, stream);
+auto LocalStorage::DumpToStream(Artifact::ObjectInfo const& info,
+ gsl::not_null<FILE*> const& stream,
+ bool raw_tree) const noexcept -> bool {
+ return IsTreeObject(info.type) and not raw_tree
+ ? TreeToStream(this, info.digest, stream)
+ : BlobToStream(this, info, stream);
}