diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/execution_api/common/common_api.hpp | 7 | ||||
-rw-r--r-- | src/buildtool/execution_api/common/execution_api.hpp | 5 | ||||
-rw-r--r-- | src/buildtool/execution_api/git/git_api.hpp | 11 | ||||
-rw-r--r-- | src/buildtool/execution_api/local/local_api.hpp | 11 | ||||
-rw-r--r-- | src/buildtool/execution_api/remote/TARGETS | 1 | ||||
-rw-r--r-- | src/buildtool/execution_api/remote/bazel/bazel_api.cpp | 27 | ||||
-rw-r--r-- | src/buildtool/execution_api/remote/bazel/bazel_api.hpp | 5 | ||||
-rw-r--r-- | src/buildtool/execution_api/serve/mr_git_api.hpp | 6 | ||||
-rw-r--r-- | src/buildtool/execution_api/serve/mr_local_api.cpp | 7 | ||||
-rw-r--r-- | src/buildtool/execution_api/serve/mr_local_api.hpp | 6 | ||||
-rw-r--r-- | src/buildtool/execution_engine/executor/TARGETS | 1 | ||||
-rw-r--r-- | src/buildtool/execution_engine/executor/executor.hpp | 90 |
12 files changed, 89 insertions, 88 deletions
diff --git a/src/buildtool/execution_api/common/common_api.hpp b/src/buildtool/execution_api/common/common_api.hpp index 991b9875..d5daa3dd 100644 --- a/src/buildtool/execution_api/common/common_api.hpp +++ b/src/buildtool/execution_api/common/common_api.hpp @@ -21,6 +21,7 @@ #include <iterator> #include <optional> #include <unordered_map> +#include <unordered_set> #include <vector> #include "gsl/gsl" @@ -39,7 +40,7 @@ /// to some given original type. template <typename T> struct MissingArtifactsInfo { - std::vector<ArtifactDigest> digests; + std::unordered_set<ArtifactDigest> digests; std::unordered_map<ArtifactDigest, T> back_map; }; @@ -69,7 +70,7 @@ template <typename TValue, typename TIterator> TIterator const& end, typename std::function<ArtifactDigest(TValue const&)> const& converter) noexcept -> std::optional<MissingArtifactsInfo<TValue>> { - std::vector<ArtifactDigest> digests; + std::unordered_set<ArtifactDigest> digests; digests.reserve(std::distance(begin, end)); MissingArtifactsInfo<TValue> res{}; for (auto it = begin; it != end; ++it) { @@ -77,7 +78,7 @@ template <typename TValue, typename TIterator> auto const inserted = res.back_map.insert({std::invoke(converter, *it), *it}); if (inserted.second) { - digests.emplace_back(inserted.first->first); + digests.emplace(inserted.first->first); } } catch (...) { return std::nullopt; diff --git a/src/buildtool/execution_api/common/execution_api.hpp b/src/buildtool/execution_api/common/execution_api.hpp index 02c78bcc..b868b57d 100644 --- a/src/buildtool/execution_api/common/execution_api.hpp +++ b/src/buildtool/execution_api/common/execution_api.hpp @@ -21,6 +21,7 @@ #include <memory> #include <optional> #include <string> +#include <unordered_set> #include <vector> #include "src/buildtool/common/artifact.hpp" // Artifact::ObjectInfo @@ -129,8 +130,8 @@ class IExecutionApi { ArtifactDigest const& digest) const noexcept -> bool = 0; [[nodiscard]] virtual auto IsAvailable( - std::vector<ArtifactDigest> const& digests) const noexcept - -> std::vector<ArtifactDigest> = 0; + std::unordered_set<ArtifactDigest> const& digests) const noexcept + -> std::unordered_set<ArtifactDigest> = 0; [[nodiscard]] virtual auto SplitBlob(ArtifactDigest const& /*blob_digest*/) const noexcept -> std::optional<std::vector<ArtifactDigest>> { diff --git a/src/buildtool/execution_api/git/git_api.hpp b/src/buildtool/execution_api/git/git_api.hpp index a6ad4196..7fd21005 100644 --- a/src/buildtool/execution_api/git/git_api.hpp +++ b/src/buildtool/execution_api/git/git_api.hpp @@ -24,6 +24,7 @@ #include <optional> #include <string> #include <unordered_map> +#include <unordered_set> #include <utility> #include <vector> @@ -327,12 +328,14 @@ class GitApi final : public IExecutionApi { .has_value(); } - [[nodiscard]] auto IsAvailable(std::vector<ArtifactDigest> const& digests) - const noexcept -> std::vector<ArtifactDigest> override { - std::vector<ArtifactDigest> result; + [[nodiscard]] auto IsAvailable( + std::unordered_set<ArtifactDigest> const& digests) const noexcept + -> std::unordered_set<ArtifactDigest> override { + std::unordered_set<ArtifactDigest> result; + result.reserve(digests.size()); for (auto const& digest : digests) { if (not IsAvailable(digest)) { - result.push_back(digest); + result.emplace(digest); } } return result; diff --git a/src/buildtool/execution_api/local/local_api.hpp b/src/buildtool/execution_api/local/local_api.hpp index 7ee74be9..f1e448a0 100644 --- a/src/buildtool/execution_api/local/local_api.hpp +++ b/src/buildtool/execution_api/local/local_api.hpp @@ -27,6 +27,7 @@ #include <sstream> #include <string> #include <unordered_map> +#include <unordered_set> #include <utility> // std::move #include <vector> @@ -311,12 +312,14 @@ class LocalApi final : public IExecutionApi { return found; } - [[nodiscard]] auto IsAvailable(std::vector<ArtifactDigest> const& digests) - const noexcept -> std::vector<ArtifactDigest> final { - std::vector<ArtifactDigest> result; + [[nodiscard]] auto IsAvailable( + std::unordered_set<ArtifactDigest> const& digests) const noexcept + -> std::unordered_set<ArtifactDigest> final { + std::unordered_set<ArtifactDigest> result; + result.reserve(digests.size()); for (auto const& digest : digests) { if (not IsAvailable(digest)) { - result.push_back(digest); + result.emplace(digest); } } return result; diff --git a/src/buildtool/execution_api/remote/TARGETS b/src/buildtool/execution_api/remote/TARGETS index f61324bd..9ea074ec 100644 --- a/src/buildtool/execution_api/remote/TARGETS +++ b/src/buildtool/execution_api/remote/TARGETS @@ -84,7 +84,6 @@ , "stage": ["src", "buildtool", "execution_api", "remote"] , "private-deps": [ "bazel_network" - , ["@", "fmt", "", "fmt"] , ["src/buildtool/common", "artifact_digest_factory"] , ["src/buildtool/common", "bazel_types"] , ["src/buildtool/common", "protocol_traits"] diff --git a/src/buildtool/execution_api/remote/bazel/bazel_api.cpp b/src/buildtool/execution_api/remote/bazel/bazel_api.cpp index ed5247e5..66f81d01 100644 --- a/src/buildtool/execution_api/remote/bazel/bazel_api.cpp +++ b/src/buildtool/execution_api/remote/bazel/bazel_api.cpp @@ -117,14 +117,15 @@ namespace { } // Fetch unknown chunks. - auto digest_set = std::unordered_set<ArtifactDigest>{chunk_digests->begin(), - chunk_digests->end()}; - auto unique_digests = - std::vector<ArtifactDigest>{digest_set.begin(), digest_set.end()}; - - auto missing_artifact_digests = other_api.IsAvailable(unique_digests); - if (not ::RetrieveToCas( - missing_artifact_digests, other_api, network, info_map)) { + auto missing_artifact_digests = other_api.IsAvailable( + std::unordered_set(chunk_digests->begin(), chunk_digests->end())); + + std::vector<ArtifactDigest> missing_digests; + missing_digests.reserve(missing_artifact_digests.size()); + std::move(missing_artifact_digests.begin(), + missing_artifact_digests.end(), + std::back_inserter(missing_digests)); + if (not ::RetrieveToCas(missing_digests, other_api, network, info_map)) { return false; } @@ -570,8 +571,8 @@ auto BazelApi::CreateAction( } [[nodiscard]] auto BazelApi::IsAvailable( - std::vector<ArtifactDigest> const& digests) const noexcept - -> std::vector<ArtifactDigest> { + std::unordered_set<ArtifactDigest> const& digests) const noexcept + -> std::unordered_set<ArtifactDigest> { auto const back_map = BackMap<bazel_re::Digest, ArtifactDigest>::Make( &digests, ArtifactDigestFactory::ToBazel); if (not back_map.has_value()) { @@ -579,11 +580,7 @@ auto BazelApi::CreateAction( } auto const bazel_result = network_->IsAvailable(back_map->GetKeys()); - auto missing = back_map->GetValues(bazel_result); - std::vector<ArtifactDigest> result; - result.reserve(missing.size()); - std::move(missing.begin(), missing.end(), std::back_inserter(result)); - return result; + return back_map->GetValues(bazel_result); } [[nodiscard]] auto BazelApi::SplitBlob(ArtifactDigest const& blob_digest) diff --git a/src/buildtool/execution_api/remote/bazel/bazel_api.hpp b/src/buildtool/execution_api/remote/bazel/bazel_api.hpp index e45e0cdf..de4662db 100644 --- a/src/buildtool/execution_api/remote/bazel/bazel_api.hpp +++ b/src/buildtool/execution_api/remote/bazel/bazel_api.hpp @@ -102,8 +102,9 @@ class BazelApi final : public IExecutionApi { [[nodiscard]] auto IsAvailable(ArtifactDigest const& digest) const noexcept -> bool final; - [[nodiscard]] auto IsAvailable(std::vector<ArtifactDigest> const& digests) - const noexcept -> std::vector<ArtifactDigest> final; + [[nodiscard]] auto IsAvailable( + std::unordered_set<ArtifactDigest> const& digests) const noexcept + -> std::unordered_set<ArtifactDigest> final; [[nodiscard]] auto RetrieveToMemory( Artifact::ObjectInfo const& artifact_info) const noexcept diff --git a/src/buildtool/execution_api/serve/mr_git_api.hpp b/src/buildtool/execution_api/serve/mr_git_api.hpp index 31f723bf..b03bfcf1 100644 --- a/src/buildtool/execution_api/serve/mr_git_api.hpp +++ b/src/buildtool/execution_api/serve/mr_git_api.hpp @@ -16,9 +16,11 @@ #define INCLUDED_SRC_BUILDTOOL_EXECUTION_API_SERVE_MR_GIT_API_HPP #include <filesystem> +#include <functional> #include <map> #include <optional> #include <string> +#include <unordered_set> #include <vector> #include "gsl/gsl" @@ -122,8 +124,8 @@ class MRGitApi final : public IExecutionApi { /// \brief Not implemented. [[nodiscard]] auto IsAvailable( - std::vector<ArtifactDigest> const& /*digests*/) const noexcept - -> std::vector<ArtifactDigest> final { + std::unordered_set<ArtifactDigest> const& /*digests*/) const noexcept + -> std::unordered_set<ArtifactDigest> final { // Not supported. return {}; } diff --git a/src/buildtool/execution_api/serve/mr_local_api.cpp b/src/buildtool/execution_api/serve/mr_local_api.cpp index 118fd564..5449b245 100644 --- a/src/buildtool/execution_api/serve/mr_local_api.cpp +++ b/src/buildtool/execution_api/serve/mr_local_api.cpp @@ -14,6 +14,7 @@ #include "src/buildtool/execution_api/serve/mr_local_api.hpp" +#include <functional> #include <utility> #include "src/buildtool/common/protocol_traits.hpp" @@ -123,8 +124,8 @@ auto MRLocalApi::IsAvailable(ArtifactDigest const& digest) const noexcept return compat_local_api_->IsAvailable(digest); } -auto MRLocalApi::IsAvailable(std::vector<ArtifactDigest> const& digests) - const noexcept -> std::vector<ArtifactDigest> { +auto MRLocalApi::IsAvailable(std::unordered_set<ArtifactDigest> const& digests) + const noexcept -> std::unordered_set<ArtifactDigest> { // This method can legitimately be called with both native and // compatible digests when in compatible mode, therefore we need to // interrogate the hash type of the input. @@ -134,7 +135,7 @@ auto MRLocalApi::IsAvailable(std::vector<ArtifactDigest> const& digests) return {}; // nothing to do } // native digests get dispatched to native local api - if (ProtocolTraits::IsNative(digests[0].GetHashType())) { + if (ProtocolTraits::IsNative(digests.begin()->GetHashType())) { return native_local_api_->IsAvailable(digests); } // compatible digests get dispatched to compatible local api diff --git a/src/buildtool/execution_api/serve/mr_local_api.hpp b/src/buildtool/execution_api/serve/mr_local_api.hpp index f930bc46..c548241e 100644 --- a/src/buildtool/execution_api/serve/mr_local_api.hpp +++ b/src/buildtool/execution_api/serve/mr_local_api.hpp @@ -19,6 +19,7 @@ #include <map> #include <optional> #include <string> +#include <unordered_set> #include <vector> #include "gsl/gsl" @@ -125,8 +126,9 @@ class MRLocalApi final : public IExecutionApi { /// \note The caller is responsible for passing vectors with digests of the /// same type. For simplicity, this method takes the first digest of the /// vector as representative for figuring out hash function type. - [[nodiscard]] auto IsAvailable(std::vector<ArtifactDigest> const& digests) - const noexcept -> std::vector<ArtifactDigest> final; + [[nodiscard]] auto IsAvailable( + std::unordered_set<ArtifactDigest> const& digests) const noexcept + -> std::unordered_set<ArtifactDigest> final; private: // retain local context references to have direct access to storages diff --git a/src/buildtool/execution_engine/executor/TARGETS b/src/buildtool/execution_engine/executor/TARGETS index 39cad1c0..ff652d75 100644 --- a/src/buildtool/execution_engine/executor/TARGETS +++ b/src/buildtool/execution_engine/executor/TARGETS @@ -32,6 +32,7 @@ , ["src/buildtool/logging", "logging"] , ["src/buildtool/progress_reporting", "progress"] , ["src/buildtool/progress_reporting", "task_tracker"] + , ["src/utils/cpp", "back_map"] , ["src/utils/cpp", "expected"] , ["src/utils/cpp", "hex_string"] , ["src/utils/cpp", "path_rebase"] diff --git a/src/buildtool/execution_engine/executor/executor.hpp b/src/buildtool/execution_engine/executor/executor.hpp index 0ec7dfe6..af0b759e 100644 --- a/src/buildtool/execution_engine/executor/executor.hpp +++ b/src/buildtool/execution_engine/executor/executor.hpp @@ -65,6 +65,7 @@ #include "src/buildtool/logging/logger.hpp" #include "src/buildtool/progress_reporting/progress.hpp" #include "src/buildtool/progress_reporting/task_tracker.hpp" +#include "src/utils/cpp/back_map.hpp" #include "src/utils/cpp/expected.hpp" #include "src/utils/cpp/hex_string.hpp" #include "src/utils/cpp/path_rebase.hpp" @@ -293,26 +294,17 @@ class ExecutorImpl { GitTree const& tree) noexcept -> bool { // create list of digests for batch check of CAS availability - std::vector<ArtifactDigest> digests; - std::unordered_map<ArtifactDigest, gsl::not_null<GitTreeEntryPtr>> - entry_map; - for (auto const& [path, entry] : tree) { - // Since GitTrees are processed here, HashFunction::Type::GitSHA1 is - // used - auto digest = - ArtifactDigestFactory::Create(HashFunction::Type::GitSHA1, - entry->Hash(), - *entry->Size(), - entry->IsTree()); - if (not digest) { - return false; - } - digests.emplace_back(*digest); - try { - entry_map.emplace(*std::move(digest), entry); - } catch (...) { - return false; - } + using ElementType = typename GitTree::entries_t::value_type; + auto const back_map = BackMap<ArtifactDigest, ElementType>::Make( + &tree, [](ElementType const& entry) { + return ArtifactDigestFactory::Create( + HashFunction::Type::GitSHA1, + entry.second->Hash(), + *entry.second->Size(), + entry.second->IsTree()); + }); + if (not back_map.has_value()) { + return false; } Logger::Log(LogLevel::Trace, [&tree]() { @@ -327,44 +319,42 @@ class ExecutorImpl { }); // find missing digests - auto missing_digests = api.IsAvailable(digests); + auto const missing_digests = api.IsAvailable(back_map->GetKeys()); + auto const missing_entries = + back_map->IterateReferences(&missing_digests); // process missing trees - for (auto const& digest : missing_digests) { - if (auto it = entry_map.find(digest); it != entry_map.end()) { - auto const& entry = it->second; - if (entry->IsTree()) { - auto const& tree = entry->Tree(); - if (not tree or not VerifyOrUploadTree(api, *tree)) { - return false; - } + for (auto const& [_, value] : missing_entries) { + auto const entry = value->second; + if (entry->IsTree()) { + auto const& tree = entry->Tree(); + if (not tree or not VerifyOrUploadTree(api, *tree)) { + return false; } } } // upload missing entries (blobs or trees) ArtifactBlobContainer container; - for (auto const& digest : missing_digests) { - if (auto it = entry_map.find(digest); it != entry_map.end()) { - auto const& entry = it->second; - auto content = entry->RawData(); - if (not content) { - return false; - } - // store and/or upload blob, taking into account the maximum - // transfer size - if (not UpdateContainerAndUpload<ArtifactDigest>( - &container, - ArtifactBlob{digest, - std::move(*content), - IsExecutableObject(entry->Type())}, - /*exception_is_fatal=*/true, - [&api](ArtifactBlobContainer&& blobs) { - return api.Upload(std::move(blobs), - /*skip_find_missing=*/true); - })) { - return false; - } + for (auto const& [digest, value] : missing_entries) { + auto const entry = value->second; + auto content = entry->RawData(); + if (not content.has_value()) { + return false; + } + // store and/or upload blob, taking into account the maximum + // transfer size + if (not UpdateContainerAndUpload<ArtifactDigest>( + &container, + ArtifactBlob{*digest, + std::move(*content), + IsExecutableObject(entry->Type())}, + /*exception_is_fatal=*/true, + [&api](ArtifactBlobContainer&& blobs) { + return api.Upload(std::move(blobs), + /*skip_find_missing=*/true); + })) { + return false; } } // upload remaining blobs |