summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/execution_api/common/TARGETS1
-rw-r--r--src/buildtool/execution_api/common/stream_dumper.hpp104
-rw-r--r--src/buildtool/execution_api/local/local_api.hpp9
-rw-r--r--src/buildtool/execution_api/local/local_cas_reader.cpp45
-rw-r--r--src/buildtool/execution_api/local/local_cas_reader.hpp20
-rw-r--r--src/buildtool/execution_api/remote/bazel/bazel_api.cpp8
-rw-r--r--src/buildtool/execution_api/remote/bazel/bazel_network.cpp120
-rw-r--r--src/buildtool/execution_api/remote/bazel/bazel_network.hpp4
-rw-r--r--src/buildtool/execution_api/remote/bazel/bazel_network_reader.cpp35
-rw-r--r--src/buildtool/execution_api/remote/bazel/bazel_network_reader.hpp16
-rw-r--r--src/buildtool/storage/local_cas.hpp11
-rw-r--r--src/buildtool/storage/local_cas.tpp116
12 files changed, 229 insertions, 260 deletions
diff --git a/src/buildtool/execution_api/common/TARGETS b/src/buildtool/execution_api/common/TARGETS
index 214e87be..825f612f 100644
--- a/src/buildtool/execution_api/common/TARGETS
+++ b/src/buildtool/execution_api/common/TARGETS
@@ -7,6 +7,7 @@
, "execution_action.hpp"
, "execution_response.hpp"
, "tree_reader.hpp"
+ , "stream_dumper.hpp"
]
, "srcs": ["execution_api.cpp"]
, "deps":
diff --git a/src/buildtool/execution_api/common/stream_dumper.hpp b/src/buildtool/execution_api/common/stream_dumper.hpp
new file mode 100644
index 00000000..31f9b292
--- /dev/null
+++ b/src/buildtool/execution_api/common/stream_dumper.hpp
@@ -0,0 +1,104 @@
+// Copyright 2024 Huawei Cloud Computing Technology Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef INCLUDED_SRC_BUILDTOOL_EXECUTION_API_COMMON_STREAM_DUMPER_HPP
+#define INCLUDED_SRC_BUILDTOOL_EXECUTION_API_COMMON_STREAM_DUMPER_HPP
+
+#include <cstdio>
+#include <optional>
+#include <string>
+#include <utility>
+
+#include "gsl/gsl"
+#include "src/buildtool/common/artifact.hpp"
+#include "src/buildtool/compatibility/compatibility.hpp"
+#include "src/buildtool/execution_api/bazel_msg/bazel_msg_factory.hpp"
+#include "src/buildtool/file_system/object_type.hpp"
+
+template <typename TImpl>
+class StreamDumper final {
+ public:
+ template <typename... Args>
+ explicit StreamDumper(Args&&... args) noexcept
+ : impl_(std::forward<Args>(args)...) {}
+
+ /// \brief Dump artifact to file stream.
+ /// Tree artifacts are pretty-printed (i.e., contents are listed) unless
+ /// raw_tree is set, then the raw tree will be written to the file stream.
+ /// \param info The object info of the artifact to dump.
+ /// \param stream The file stream to dump to.
+ /// \param raw_tree Dump tree as raw blob.
+ /// \returns true on success.
+ [[nodiscard]] auto DumpToStream(Artifact::ObjectInfo const& info,
+ gsl::not_null<FILE*> const& stream,
+ bool raw_tree) const noexcept -> bool {
+ const bool is_tree = IsTreeObject(info.type);
+ if (is_tree and raw_tree) {
+ return DumpRawTree(info, stream);
+ }
+ return is_tree ? DumpTree(info, stream) : DumpBlob(info, stream);
+ }
+
+ private:
+ TImpl impl_;
+
+ [[nodiscard]] auto DumpRawTree(
+ Artifact::ObjectInfo const& info,
+ gsl::not_null<FILE*> const& stream) const noexcept -> bool {
+ auto writer = [this, &stream](std::string const& data) -> bool {
+ return DumpString(data, stream);
+ };
+ return impl_.DumpRawTree(info, writer);
+ }
+
+ [[nodiscard]] auto DumpTree(
+ Artifact::ObjectInfo const& info,
+ gsl::not_null<FILE*> const& stream) const noexcept -> bool {
+ if (Compatibility::IsCompatible()) {
+ auto directory = impl_.ReadDirectory(info.digest);
+ auto data = directory
+ ? BazelMsgFactory::DirectoryToString(*directory)
+ : std::nullopt;
+ if (data) {
+ return DumpString(*data, stream);
+ }
+ }
+ else {
+ auto entries = impl_.ReadGitTree(info.digest);
+ auto data = entries ? BazelMsgFactory::GitTreeToString(*entries)
+ : std::nullopt;
+ if (data) {
+ return DumpString(*data, stream);
+ }
+ }
+ return false;
+ }
+
+ [[nodiscard]] auto DumpBlob(
+ Artifact::ObjectInfo const& info,
+ gsl::not_null<FILE*> const& stream) const noexcept -> bool {
+ auto writer = [this, &stream](std::string const& data) -> bool {
+ return DumpString(data, stream);
+ };
+ return impl_.DumpBlob(info, writer);
+ }
+
+ [[nodiscard]] auto DumpString(
+ std::string const& data,
+ gsl::not_null<FILE*> const& stream) const noexcept -> bool {
+ return std::fwrite(data.data(), 1, data.size(), stream) == data.size();
+ }
+};
+
+#endif // INCLUDED_SRC_BUILDTOOL_EXECUTION_API_COMMON_STREAM_DUMPER_HPP
diff --git a/src/buildtool/execution_api/local/local_api.hpp b/src/buildtool/execution_api/local/local_api.hpp
index c81b75c1..b9be5aed 100644
--- a/src/buildtool/execution_api/local/local_api.hpp
+++ b/src/buildtool/execution_api/local/local_api.hpp
@@ -37,6 +37,7 @@
#include "src/buildtool/execution_api/bazel_msg/blob_tree.hpp"
#include "src/buildtool/execution_api/common/common_api.hpp"
#include "src/buildtool/execution_api/common/execution_api.hpp"
+#include "src/buildtool/execution_api/common/stream_dumper.hpp"
#include "src/buildtool/execution_api/common/tree_reader.hpp"
#include "src/buildtool/execution_api/execution_service/cas_utils.hpp"
#include "src/buildtool/execution_api/git/git_api.hpp"
@@ -141,13 +142,13 @@ class LocalApi final : public IExecutionApi {
std::vector<Artifact::ObjectInfo> const& artifacts_info,
std::vector<int> const& fds,
bool raw_tree) noexcept -> bool final {
+ auto dumper = StreamDumper<LocalCasReader>{storage_->CAS()};
return CommonRetrieveToFds(
artifacts_info,
fds,
- [&cas = storage_->CAS(), &raw_tree](
- Artifact::ObjectInfo const& info,
- gsl::not_null<FILE*> const& out) {
- return cas.DumpToStream(info, out, raw_tree);
+ [&dumper, &raw_tree](Artifact::ObjectInfo const& info,
+ gsl::not_null<FILE*> const& out) {
+ return dumper.DumpToStream(info, out, raw_tree);
},
[&repo_config = repo_config_, &raw_tree](
Artifact::ObjectInfo const& info, int fd) {
diff --git a/src/buildtool/execution_api/local/local_cas_reader.cpp b/src/buildtool/execution_api/local/local_cas_reader.cpp
index 411bc5d7..a8933adc 100644
--- a/src/buildtool/execution_api/local/local_cas_reader.cpp
+++ b/src/buildtool/execution_api/local/local_cas_reader.cpp
@@ -14,6 +14,10 @@
#include "src/buildtool/execution_api/local/local_cas_reader.hpp"
+#include <cstdio>
+#include <memory>
+
+#include "gsl/gsl"
#include "src/buildtool/crypto/hash_function.hpp"
#include "src/buildtool/execution_api/bazel_msg/bazel_msg_factory.hpp"
#include "src/buildtool/file_system/file_system_manager.hpp"
@@ -64,3 +68,44 @@ auto LocalCasReader::ReadGitTree(ArtifactDigest const& digest) const noexcept
Logger::Log(LogLevel::Debug, "Tree {} not found in CAS", digest.hash());
return std::nullopt;
}
+
+auto LocalCasReader::DumpRawTree(Artifact::ObjectInfo const& info,
+ DumpCallback const& dumper) const noexcept
+ -> bool {
+ auto path = cas_.TreePath(info.digest);
+ return path ? DumpRaw(*path, dumper) : false;
+}
+
+auto LocalCasReader::DumpBlob(Artifact::ObjectInfo const& info,
+ DumpCallback const& dumper) const noexcept
+ -> bool {
+ auto path = cas_.BlobPath(info.digest, IsExecutableObject(info.type));
+ return path ? DumpRaw(*path, dumper) : false;
+}
+
+auto LocalCasReader::DumpRaw(std::filesystem::path const& path,
+ DumpCallback const& dumper) noexcept -> bool {
+ auto closer = [](gsl::owner<FILE*> file) -> void {
+ if (file != nullptr) {
+ std::fclose(file);
+ }
+ };
+ auto in = std::shared_ptr<FILE>{std::fopen(path.c_str(), "rb"), closer};
+ if (not in) {
+ return false;
+ }
+
+ constexpr std::size_t kChunkSize{512};
+ std::string buffer(kChunkSize, '\0');
+ while (auto size = std::fread(buffer.data(), 1, buffer.size(), in.get())) {
+ try {
+ buffer.resize(size);
+ if (not std::invoke(dumper, buffer)) {
+ return false;
+ }
+ } catch (...) {
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/src/buildtool/execution_api/local/local_cas_reader.hpp b/src/buildtool/execution_api/local/local_cas_reader.hpp
index 69baf3a9..9618dbc4 100644
--- a/src/buildtool/execution_api/local/local_cas_reader.hpp
+++ b/src/buildtool/execution_api/local/local_cas_reader.hpp
@@ -15,8 +15,12 @@
#ifndef INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_LOCAL_CAS_READER_HPP
#define INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_LOCAL_CAS_READER_HPP
+#include <filesystem>
+#include <functional>
#include <optional>
+#include <string>
+#include "src/buildtool/common/artifact.hpp"
#include "src/buildtool/common/artifact_digest.hpp"
#include "src/buildtool/common/bazel_types.hpp"
#include "src/buildtool/file_system/git_repo.hpp"
@@ -24,6 +28,8 @@
class LocalCasReader final {
public:
+ using DumpCallback = std::function<bool(std::string const&)>;
+
explicit LocalCasReader(LocalCAS<true> const& cas) noexcept : cas_(cas) {}
[[nodiscard]] auto ReadDirectory(ArtifactDigest const& digest)
@@ -32,8 +38,20 @@ class LocalCasReader final {
[[nodiscard]] auto ReadGitTree(ArtifactDigest const& digest) const noexcept
-> std::optional<GitRepo::tree_entries_t>;
+ [[nodiscard]] auto DumpRawTree(Artifact::ObjectInfo const& info,
+ DumpCallback const& dumper) const noexcept
+ -> bool;
+
+ [[nodiscard]] auto DumpBlob(Artifact::ObjectInfo const& info,
+ DumpCallback const& dumper) const noexcept
+ -> bool;
+
private:
LocalCAS<true> const& cas_;
+
+ [[nodiscard]] static auto DumpRaw(std::filesystem::path const& path,
+ DumpCallback const& dumper) noexcept
+ -> bool;
};
-#endif // INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_LOCAL_CAS_READER_HPP \ No newline at end of file
+#endif // INCLUDED_SRC_BUILDTOOL_EXECUTION_API_LOCAL_LOCAL_CAS_READER_HPP
diff --git a/src/buildtool/execution_api/remote/bazel/bazel_api.cpp b/src/buildtool/execution_api/remote/bazel/bazel_api.cpp
index 47d024f9..0f1fdd04 100644
--- a/src/buildtool/execution_api/remote/bazel/bazel_api.cpp
+++ b/src/buildtool/execution_api/remote/bazel/bazel_api.cpp
@@ -31,6 +31,7 @@
#include "src/buildtool/execution_api/bazel_msg/bazel_common.hpp"
#include "src/buildtool/execution_api/bazel_msg/bazel_msg_factory.hpp"
#include "src/buildtool/execution_api/common/common_api.hpp"
+#include "src/buildtool/execution_api/common/stream_dumper.hpp"
#include "src/buildtool/execution_api/common/tree_reader.hpp"
#include "src/buildtool/execution_api/remote/bazel/bazel_ac_client.hpp"
#include "src/buildtool/execution_api/remote/bazel/bazel_action.hpp"
@@ -284,12 +285,13 @@ auto BazelApi::CreateAction(
std::vector<Artifact::ObjectInfo> const& artifacts_info,
std::vector<int> const& fds,
bool raw_tree) noexcept -> bool {
+ auto dumper = StreamDumper<BazelNetworkReader>{*network_};
return CommonRetrieveToFds(
artifacts_info,
fds,
- [&network = network_, &raw_tree](Artifact::ObjectInfo const& info,
- gsl::not_null<FILE*> const& out) {
- return network->DumpToStream(info, out, raw_tree);
+ [&dumper, &raw_tree](Artifact::ObjectInfo const& info,
+ gsl::not_null<FILE*> const& out) {
+ return dumper.DumpToStream(info, out, raw_tree);
},
std::nullopt // remote can't fallback to Git
);
diff --git a/src/buildtool/execution_api/remote/bazel/bazel_network.cpp b/src/buildtool/execution_api/remote/bazel/bazel_network.cpp
index 485e65dc..4cc3a274 100644
--- a/src/buildtool/execution_api/remote/bazel/bazel_network.cpp
+++ b/src/buildtool/execution_api/remote/bazel/bazel_network.cpp
@@ -23,118 +23,6 @@
#include "src/buildtool/logging/log_level.hpp"
#include "src/buildtool/logging/logger.hpp"
-namespace {
-
-[[nodiscard]] auto ReadDirectory(
- gsl::not_null<BazelNetwork const*> const& network,
- bazel_re::Digest const& digest) noexcept
- -> std::optional<bazel_re::Directory> {
- auto blobs = network->ReadBlobs({digest}).Next();
- if (blobs.size() == 1) {
- return BazelMsgFactory::MessageFromString<bazel_re::Directory>(
- blobs.at(0).data);
- }
- Logger::Log(LogLevel::Debug,
- "Directory {} not found in CAS",
- NativeSupport::Unprefix(digest.hash()));
- return std::nullopt;
-}
-
-[[nodiscard]] auto ReadGitTree(
- gsl::not_null<BazelNetwork const*> const& network,
- bazel_re::Digest const& digest) noexcept
- -> std::optional<GitRepo::tree_entries_t> {
- auto blobs = network->ReadBlobs({digest}).Next();
- if (blobs.size() == 1) {
- auto const& content = blobs.at(0).data;
- auto check_symlinks =
- [&network](std::vector<bazel_re::Digest> const& ids) {
- auto size = ids.size();
- auto reader = network->ReadBlobs(ids);
- auto blobs = reader.Next();
- std::size_t count{};
- while (not blobs.empty()) {
- if (count + blobs.size() > size) {
- Logger::Log(LogLevel::Debug,
- "received more blobs than requested.");
- return false;
- }
- for (auto const& blob : blobs) {
- if (not PathIsNonUpwards(blob.data)) {
- return false;
- }
- }
- count += blobs.size();
- blobs = reader.Next();
- }
- return true;
- };
- return GitRepo::ReadTreeData(
- content,
- HashFunction::ComputeTreeHash(content).Bytes(),
- check_symlinks,
- /*is_hex_id=*/false);
- }
- Logger::Log(LogLevel::Debug,
- "Tree {} not found in CAS",
- NativeSupport::Unprefix(digest.hash()));
- return std::nullopt;
-}
-
-[[nodiscard]] auto TreeToStream(
- gsl::not_null<BazelNetwork const*> const& network,
- bazel_re::Digest const& tree_digest,
- gsl::not_null<FILE*> const& stream,
- bool raw_tree) noexcept -> bool {
- if (raw_tree) {
- auto blobs = network->ReadBlobs({tree_digest}).Next();
- if (blobs.size() != 1) {
- Logger::Log(LogLevel::Debug,
- "Object {} not found in CAS",
- NativeSupport::Unprefix(tree_digest.hash()));
- return false;
- }
- auto const& str = blobs.at(0).data;
- std::fwrite(str.data(), 1, str.size(), stream);
- return true;
- }
- if (Compatibility::IsCompatible()) {
- if (auto dir = ReadDirectory(network, tree_digest)) {
- if (auto data = BazelMsgFactory::DirectoryToString(*dir)) {
- auto const& str = *data;
- std::fwrite(str.data(), 1, str.size(), stream);
- return true;
- }
- }
- }
- else {
- if (auto entries = ReadGitTree(network, tree_digest)) {
- if (auto data = BazelMsgFactory::GitTreeToString(*entries)) {
- auto const& str = *data;
- std::fwrite(str.data(), 1, str.size(), stream);
- return true;
- }
- }
- }
- return false;
-}
-
-[[nodiscard]] auto BlobToStream(
- gsl::not_null<BazelNetwork const*> const& network,
- bazel_re::Digest const& blob_digest,
- gsl::not_null<FILE*> const& stream) noexcept -> bool {
- auto reader = network->IncrementalReadSingleBlob(blob_digest);
- auto data = reader.Next();
- while (data and not data->empty()) {
- auto const& str = *data;
- std::fwrite(str.data(), 1, str.size(), stream);
- data = reader.Next();
- }
- return data.has_value();
-}
-
-} // namespace
-
BazelNetwork::BazelNetwork(std::string instance_name,
std::string const& host,
Port port,
@@ -314,11 +202,3 @@ auto BazelNetwork::QueryFullTree(bazel_re::Digest const& digest) const noexcept
}
return cas_->GetTree(instance_name_, digest, kMaxBatchTransferSize);
}
-
-auto BazelNetwork::DumpToStream(Artifact::ObjectInfo const& info,
- gsl::not_null<FILE*> const& stream,
- bool raw_tree) const noexcept -> bool {
- return IsTreeObject(info.type)
- ? TreeToStream(this, info.digest, stream, raw_tree)
- : BlobToStream(this, info.digest, stream);
-}
diff --git a/src/buildtool/execution_api/remote/bazel/bazel_network.hpp b/src/buildtool/execution_api/remote/bazel/bazel_network.hpp
index 6ee44921..82a20c4d 100644
--- a/src/buildtool/execution_api/remote/bazel/bazel_network.hpp
+++ b/src/buildtool/execution_api/remote/bazel/bazel_network.hpp
@@ -110,10 +110,6 @@ class BazelNetwork {
std::vector<std::string> const& output_files) const noexcept
-> std::optional<bazel_re::ActionResult>;
- [[nodiscard]] auto DumpToStream(Artifact::ObjectInfo const& info,
- gsl::not_null<FILE*> const& stream,
- bool raw_tree) const noexcept -> bool;
-
/// \brief Query full tree from remote CAS. Note that this is currently not
// supported by Buildbarn revision c3c06bbe2a.
[[nodiscard]] auto QueryFullTree(bazel_re::Digest const& digest)
diff --git a/src/buildtool/execution_api/remote/bazel/bazel_network_reader.cpp b/src/buildtool/execution_api/remote/bazel/bazel_network_reader.cpp
index ee0fbc78..a0e96237 100644
--- a/src/buildtool/execution_api/remote/bazel/bazel_network_reader.cpp
+++ b/src/buildtool/execution_api/remote/bazel/bazel_network_reader.cpp
@@ -92,6 +92,41 @@ auto BazelNetworkReader::ReadGitTree(ArtifactDigest const& digest)
return std::nullopt;
}
+auto BazelNetworkReader::DumpRawTree(Artifact::ObjectInfo const& info,
+ DumpCallback const& dumper) const noexcept
+ -> bool {
+ auto blobs = network_.ReadBlobs({info.digest}).Next();
+ if (blobs.size() != 1) {
+ Logger::Log(
+ LogLevel::Debug, "Object {} not found in CAS", info.digest.hash());
+ return false;
+ }
+
+ try {
+ return std::invoke(dumper, blobs.at(0).data);
+ } catch (...) {
+ return false;
+ }
+}
+
+auto BazelNetworkReader::DumpBlob(Artifact::ObjectInfo const& info,
+ DumpCallback const& dumper) const noexcept
+ -> bool {
+ auto reader = network_.IncrementalReadSingleBlob(info.digest);
+ auto data = reader.Next();
+ while (data and not data->empty()) {
+ try {
+ if (not std::invoke(dumper, *data)) {
+ return false;
+ }
+ } catch (...) {
+ return false;
+ }
+ data = reader.Next();
+ }
+ return data.has_value();
+}
+
auto BazelNetworkReader::MakeAuxiliaryMap(
std::vector<bazel_re::Directory>&& full_tree) noexcept
-> std::optional<DirectoryMap> {
diff --git a/src/buildtool/execution_api/remote/bazel/bazel_network_reader.hpp b/src/buildtool/execution_api/remote/bazel/bazel_network_reader.hpp
index 8d46c9f8..fb5f5184 100644
--- a/src/buildtool/execution_api/remote/bazel/bazel_network_reader.hpp
+++ b/src/buildtool/execution_api/remote/bazel/bazel_network_reader.hpp
@@ -15,9 +15,13 @@
#ifndef INCLUDED_SRC_BUILDTOOL_EXECUTION_API_REMOTE_BAZEL_BAZEL_TREE_READER_HPP
#define INCLUDED_SRC_BUILDTOOL_EXECUTION_API_REMOTE_BAZEL_BAZEL_TREE_READER_HPP
+#include <filesystem>
+#include <functional>
#include <optional>
+#include <string>
#include <unordered_map>
+#include "src/buildtool/common/artifact.hpp"
#include "src/buildtool/common/artifact_digest.hpp"
#include "src/buildtool/common/bazel_types.hpp"
#include "src/buildtool/execution_api/remote/bazel/bazel_network.hpp"
@@ -25,6 +29,8 @@
class BazelNetworkReader final {
public:
+ using DumpCallback = std::function<bool(std::string const&)>;
+
explicit BazelNetworkReader(
BazelNetwork const& network,
std::optional<ArtifactDigest> request_remote_tree =
@@ -36,6 +42,14 @@ class BazelNetworkReader final {
[[nodiscard]] auto ReadGitTree(ArtifactDigest const& digest) const noexcept
-> std::optional<GitRepo::tree_entries_t>;
+ [[nodiscard]] auto DumpRawTree(Artifact::ObjectInfo const& info,
+ DumpCallback const& dumper) const noexcept
+ -> bool;
+
+ [[nodiscard]] auto DumpBlob(Artifact::ObjectInfo const& info,
+ DumpCallback const& dumper) const noexcept
+ -> bool;
+
private:
using DirectoryMap =
std::unordered_map<bazel_re::Digest, bazel_re::Directory>;
@@ -48,4 +62,4 @@ class BazelNetworkReader final {
-> std::optional<DirectoryMap>;
};
-#endif // INCLUDED_SRC_BUILDTOOL_EXECUTION_API_REMOTE_BAZEL_BAZEL_TREE_READER_HPP \ No newline at end of file
+#endif // INCLUDED_SRC_BUILDTOOL_EXECUTION_API_REMOTE_BAZEL_BAZEL_TREE_READER_HPP
diff --git a/src/buildtool/storage/local_cas.hpp b/src/buildtool/storage/local_cas.hpp
index 9288e423..9309ef5d 100644
--- a/src/buildtool/storage/local_cas.hpp
+++ b/src/buildtool/storage/local_cas.hpp
@@ -199,17 +199,6 @@ class LocalCAS {
std::string const& tree_data)
const noexcept -> std::optional<LargeObjectError>;
- /// \brief Dump artifact to file stream.
- /// Tree artifacts are pretty-printed (i.e., contents are listed) unless
- /// raw_tree is set, then the raw tree will be written to the file stream.
- /// \param info The object info of the artifact to dump.
- /// \param stream The file stream to dump to.
- /// \param raw_tree Dump tree as raw blob.
- /// \returns true on success.
- [[nodiscard]] auto DumpToStream(Artifact::ObjectInfo const& info,
- gsl::not_null<FILE*> const& stream,
- bool raw_tree) const noexcept -> bool;
-
/// \brief Uplink blob from this generation to latest LocalCAS generation.
/// Performs a synchronization if requested and if blob is only available
/// with inverse x-bit. This function is only available for instances that
diff --git a/src/buildtool/storage/local_cas.tpp b/src/buildtool/storage/local_cas.tpp
index 664606c9..4850cbd7 100644
--- a/src/buildtool/storage/local_cas.tpp
+++ b/src/buildtool/storage/local_cas.tpp
@@ -25,112 +25,6 @@
namespace detail {
-template <class T_CAS>
-[[nodiscard]] auto ReadDirectory(T_CAS const& cas,
- bazel_re::Digest const& digest) noexcept
- -> std::optional<bazel_re::Directory> {
- if (auto const path = cas.TreePath(digest)) {
- if (auto const content = FileSystemManager::ReadFile(*path)) {
- return BazelMsgFactory::MessageFromString<bazel_re::Directory>(
- *content);
- }
- }
- Logger::Log(LogLevel::Error,
- "Directory {} not found in CAS",
- NativeSupport::Unprefix(digest.hash()));
- return std::nullopt;
-}
-
-template <class T_CAS>
-[[nodiscard]] auto ReadGitTree(T_CAS const& cas,
- bazel_re::Digest const& digest) noexcept
- -> std::optional<GitRepo::tree_entries_t> {
- if (auto const path = cas.TreePath(digest)) {
- if (auto const content = FileSystemManager::ReadFile(*path)) {
- auto check_symlinks =
- [&cas](std::vector<bazel_re::Digest> const& ids) {
- for (auto const& id : ids) {
- auto link_path =
- cas.BlobPath(id, /*is_executable=*/false);
- if (not link_path) {
- return false;
- }
- // in the local CAS we store as files
- auto content = FileSystemManager::ReadFile(*link_path);
- if (not content or not PathIsNonUpwards(*content)) {
- return false;
- }
- }
- return true;
- };
- return GitRepo::ReadTreeData(
- *content,
- HashFunction::ComputeTreeHash(*content).Bytes(),
- check_symlinks,
- /*is_hex_id=*/false);
- }
- }
- Logger::Log(LogLevel::Debug,
- "Tree {} not found in CAS",
- NativeSupport::Unprefix(digest.hash()));
- return std::nullopt;
-}
-
-[[nodiscard]] inline 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;
-}
-
-template <class T_CAS>
-[[nodiscard]] auto TreeToStream(T_CAS const& cas,
- bazel_re::Digest const& tree_digest,
- gsl::not_null<FILE*> const& stream) noexcept
- -> bool {
- if (Compatibility::IsCompatible()) {
- if (auto dir = ReadDirectory(cas, tree_digest)) {
- return DumpToStream(stream,
- BazelMsgFactory::DirectoryToString(*dir));
- }
- }
- else {
- if (auto entries = ReadGitTree(cas, tree_digest)) {
- return DumpToStream(stream,
- BazelMsgFactory::GitTreeToString(*entries));
- }
- }
- return false;
-}
-
-template <class T_CAS>
-[[nodiscard]] auto BlobToStream(T_CAS const& cas,
- Artifact::ObjectInfo const& blob_info,
- gsl::not_null<FILE*> const& stream) noexcept
- -> bool {
- constexpr std::size_t kChunkSize{512};
- auto path =
- cas.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 = cas.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)) {
- std::fwrite(data.data(), 1, size, stream);
- }
- std::fclose(in);
- return true;
- }
- }
- return false;
-}
-
[[nodiscard]] static inline auto CheckDigestConsistency(
bazel_re::Digest const& lhs,
bazel_re::Digest const& rhs) noexcept -> bool {
@@ -147,16 +41,6 @@ template <class T_CAS>
} // namespace detail
template <bool kDoGlobalUplink>
-auto LocalCAS<kDoGlobalUplink>::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
- ? detail::TreeToStream(*this, info.digest, stream)
- : detail::BlobToStream(*this, info, stream);
-}
-
-template <bool kDoGlobalUplink>
template <bool kIsLocalGeneration>
requires(kIsLocalGeneration) auto LocalCAS<kDoGlobalUplink>::LocalUplinkBlob(
LocalGenerationCAS const& latest,