summaryrefslogtreecommitdiff
path: root/src/buildtool/execution_api/local/local_cas_reader.cpp
diff options
context:
space:
mode:
authorMaksim Denisov <denisov.maksim@huawei.com>2024-07-30 17:10:04 +0200
committerMaksim Denisov <denisov.maksim@huawei.com>2024-08-07 14:43:19 +0200
commit3632d10530c6ec4f5241191e1912836c06136215 (patch)
treefb4399bbf89f1e97bda92bf67cbbe3d712f50a9c /src/buildtool/execution_api/local/local_cas_reader.cpp
parent010944c231bc32918ec70274e4da7aad710c288f (diff)
downloadjustbuild-3632d10530c6ec4f5241191e1912836c06136215.tar.gz
Generate bazel trees in LocalCasReader
...and use this functionality in ExecutionServer
Diffstat (limited to 'src/buildtool/execution_api/local/local_cas_reader.cpp')
-rw-r--r--src/buildtool/execution_api/local/local_cas_reader.cpp70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/buildtool/execution_api/local/local_cas_reader.cpp b/src/buildtool/execution_api/local/local_cas_reader.cpp
index fd7ede7f..56915fa9 100644
--- a/src/buildtool/execution_api/local/local_cas_reader.cpp
+++ b/src/buildtool/execution_api/local/local_cas_reader.cpp
@@ -14,8 +14,13 @@
#include "src/buildtool/execution_api/local/local_cas_reader.hpp"
+#include <algorithm>
#include <cstdio>
#include <memory>
+#include <stack>
+#include <unordered_map>
+#include <utility>
+#include <vector>
#include "gsl/gsl"
#include "src/buildtool/crypto/hash_function.hpp"
@@ -25,6 +30,13 @@
#include "src/buildtool/logging/logger.hpp"
#include "src/utils/cpp/path.hpp"
+namespace {
+[[nodiscard]] auto AssembleTree(
+ bazel_re::Directory root,
+ std::unordered_map<ArtifactDigest, bazel_re::Directory> directories)
+ -> bazel_re::Tree;
+} // namespace
+
auto LocalCasReader::ReadDirectory(ArtifactDigest const& digest) const noexcept
-> std::optional<bazel_re::Directory> {
if (auto const path = cas_.TreePath(digest)) {
@@ -38,6 +50,38 @@ auto LocalCasReader::ReadDirectory(ArtifactDigest const& digest) const noexcept
return std::nullopt;
}
+auto LocalCasReader::MakeTree(ArtifactDigest const& root) const noexcept
+ -> std::optional<bazel_re::Tree> {
+ try {
+ std::unordered_map<ArtifactDigest, bazel_re::Directory> directories;
+
+ std::stack<ArtifactDigest> to_check;
+ to_check.push(root);
+ while (not to_check.empty()) {
+ auto current = to_check.top();
+ to_check.pop();
+
+ if (directories.contains(current)) {
+ continue;
+ }
+
+ auto read_dir = ReadDirectory(current);
+ if (not read_dir) {
+ return std::nullopt;
+ }
+ for (auto const& node : read_dir->directories()) {
+ to_check.push(ArtifactDigest{node.digest()});
+ }
+ directories.insert_or_assign(std::move(current),
+ *std::move(read_dir));
+ }
+ auto root_directory = directories.extract(root).mapped();
+ return AssembleTree(std::move(root_directory), std::move(directories));
+ } catch (...) {
+ return std::nullopt;
+ }
+}
+
auto LocalCasReader::ReadGitTree(ArtifactDigest const& digest) const noexcept
-> std::optional<GitRepo::tree_entries_t> {
if (auto const path = cas_.TreePath(digest)) {
@@ -112,3 +156,29 @@ auto LocalCasReader::DumpRaw(std::filesystem::path const& path,
}
return true;
}
+
+namespace {
+[[nodiscard]] auto AssembleTree(
+ bazel_re::Directory root,
+ std::unordered_map<ArtifactDigest, bazel_re::Directory> directories)
+ -> bazel_re::Tree {
+ using Pair = std::pair<ArtifactDigest const, bazel_re::Directory>;
+ std::vector<Pair*> sorted;
+ sorted.reserve(directories.size());
+ for (auto& p : directories) {
+ sorted.push_back(&p);
+ }
+ std::sort(sorted.begin(), sorted.end(), [](Pair const* l, Pair const* r) {
+ return l->first.hash() < r->first.hash();
+ });
+
+ ::bazel_re::Tree result{};
+ (*result.mutable_root()) = std::move(root);
+ result.mutable_children()->Reserve(gsl::narrow<int>(sorted.size()));
+ std::transform(sorted.begin(),
+ sorted.end(),
+ ::pb::back_inserter(result.mutable_children()),
+ [](Pair* p) { return std::move(p->second); });
+ return result;
+}
+} // namespace