summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/execution_api/remote/bazel/bazel_network_reader.cpp63
1 files changed, 48 insertions, 15 deletions
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 22416dd9..d57991b6 100644
--- a/src/buildtool/execution_api/remote/bazel/bazel_network_reader.cpp
+++ b/src/buildtool/execution_api/remote/bazel/bazel_network_reader.cpp
@@ -28,6 +28,7 @@
#include "src/buildtool/file_system/object_type.hpp"
#include "src/buildtool/logging/log_level.hpp"
#include "src/buildtool/logging/logger.hpp"
+#include "src/utils/cpp/back_map.hpp"
#include "src/utils/cpp/expected.hpp"
#include "src/utils/cpp/gsl.hpp"
#include "src/utils/cpp/path.hpp"
@@ -201,26 +202,58 @@ auto BazelNetworkReader::ReadIncrementally(
auto BazelNetworkReader::BatchReadBlobs(
std::vector<ArtifactDigest> const& digests) const noexcept
-> std::vector<ArtifactBlob> {
+ // Convert artifacts to bazel digests:
std::vector<bazel_re::Digest> bazel_digests;
bazel_digests.reserve(digests.size());
- std::transform(digests.begin(),
- digests.end(),
- std::back_inserter(bazel_digests),
- [](ArtifactDigest const& digest) {
- return ArtifactDigestFactory::ToBazel(digest);
- });
-
- std::vector<BazelBlob> const result = cas_.BatchReadBlobs(
+ for (ArtifactDigest const& digest : digests) {
+ bazel_digests.push_back(ArtifactDigestFactory::ToBazel(digest));
+ }
+
+ // Batch blobs:
+ std::vector<BazelBlob> bazel_blobs = cas_.BatchReadBlobs(
instance_name_, bazel_digests.begin(), bazel_digests.end());
+ // Map digests to blobs for further lookup:
+ auto const back_map = BackMap<bazel_re::Digest, BazelBlob>::Make(
+ &bazel_blobs, [](BazelBlob const& blob) { return blob.digest; });
+
+ if (not back_map.has_value()) {
+ return {};
+ }
+
std::vector<ArtifactBlob> artifacts;
- artifacts.reserve(result.size());
- for (auto const& blob : result) {
- if (auto hash_info = Validate(blob)) {
- artifacts.emplace_back(
- ArtifactDigest{*std::move(hash_info), blob.data->size()},
- blob.data,
- blob.is_exec);
+ artifacts.reserve(digests.size());
+
+ // To not validate blobs several times, hash the result of validation:
+ std::unordered_map<std::size_t, ArtifactBlob const*> validated;
+ validated.reserve(digests.size());
+
+ auto const hasher = std::hash<ArtifactDigest>{};
+ for (ArtifactDigest const& digest : digests) {
+ std::size_t const hash = std::invoke(hasher, digest);
+ // If the blob has been validated already, just return the result:
+ if (auto it = validated.find(hash); it != validated.end()) {
+ if (it->second != nullptr) {
+ artifacts.push_back(*it->second);
+ }
+ continue;
+ }
+
+ // Blob hasn't been processed yet, perform validation:
+ auto value =
+ back_map->GetReference(ArtifactDigestFactory::ToBazel(digest));
+ if (not value.has_value()) {
+ continue;
+ }
+
+ ArtifactBlob artifact_blob{
+ digest, value.value()->data, value.value()->is_exec};
+
+ if (Validate(artifact_blob)) {
+ validated[hash] = &artifacts.emplace_back(std::move(artifact_blob));
+ }
+ else {
+ validated[hash] = nullptr;
}
}
return artifacts;