diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/build_engine/target_map/built_in_rules.cpp | 4 | ||||
-rw-r--r-- | src/buildtool/build_engine/target_map/target_cache.cpp | 9 | ||||
-rw-r--r-- | src/buildtool/build_engine/target_map/target_map.cpp | 4 | ||||
-rw-r--r-- | src/buildtool/common/TARGETS | 1 | ||||
-rw-r--r-- | src/buildtool/common/artifact.cpp | 5 | ||||
-rw-r--r-- | src/buildtool/common/artifact.hpp | 19 | ||||
-rw-r--r-- | src/buildtool/common/artifact_description.hpp | 6 | ||||
-rw-r--r-- | src/buildtool/common/artifact_digest.hpp | 59 | ||||
-rw-r--r-- | src/buildtool/common/artifact_factory.hpp | 3 | ||||
-rw-r--r-- | src/buildtool/common/repository_config.cpp | 2 | ||||
-rw-r--r-- | src/buildtool/execution_api/local/local_ac.hpp | 6 | ||||
-rw-r--r-- | src/buildtool/execution_api/local/local_api.hpp | 2 | ||||
-rw-r--r-- | src/buildtool/execution_api/local/local_cas.hpp | 8 | ||||
-rw-r--r-- | src/buildtool/execution_engine/executor/executor.hpp | 4 | ||||
-rw-r--r-- | src/buildtool/file_system/file_root.hpp | 8 | ||||
-rw-r--r-- | src/buildtool/graph_traverser/graph_traverser.hpp | 3 |
16 files changed, 89 insertions, 54 deletions
diff --git a/src/buildtool/build_engine/target_map/built_in_rules.cpp b/src/buildtool/build_engine/target_map/built_in_rules.cpp index 18786b60..786b4d58 100644 --- a/src/buildtool/build_engine/target_map/built_in_rules.cpp +++ b/src/buildtool/build_engine/target_map/built_in_rules.cpp @@ -150,9 +150,7 @@ void FileGenRuleWithDeps( auto stage = ExpressionPtr{Expression::map_t{ file_name_val->String(), ExpressionPtr{ArtifactDescription{ - {HashFunction::ComputeBlobHash(data_val->String()).HexString(), - data_val->String().size()}, - ObjectType::File}}}}; + ArtifactDigest::Create(data_val->String()), ObjectType::File}}}}; auto vars_set = std::unordered_set<std::string>{}; vars_set.insert(param_vars->begin(), param_vars->end()); diff --git a/src/buildtool/build_engine/target_map/target_cache.cpp b/src/buildtool/build_engine/target_map/target_cache.cpp index d9fea021..8ba54557 100644 --- a/src/buildtool/build_engine/target_map/target_cache.cpp +++ b/src/buildtool/build_engine/target_map/target_cache.cpp @@ -23,8 +23,7 @@ auto TargetCache::Key::Create(BuildMaps::Base::EntityName const& target, {"effective_config", effective_config.ToString()}}}; static auto const& cas = LocalCAS<ObjectType::File>::Instance(); if (auto target_key = cas.StoreBlobFromBytes(target_desc.dump(2))) { - return Key{ - {ArtifactDigest{std::move(*target_key)}, ObjectType::File}}; + return Key{{ArtifactDigest{*target_key}, ObjectType::File}}; } } } catch (std::exception const& ex) { @@ -54,9 +53,9 @@ auto TargetCache::Entry::ToResult() const -> std::optional<TargetResult> { auto TargetCache::Store(Key const& key, Entry const& value) const noexcept -> bool { if (auto digest = CAS().StoreBlobFromBytes(value.ToJson().dump(2))) { - auto data = Artifact::ObjectInfo{ArtifactDigest{std::move(*digest)}, - ObjectType::File} - .ToString(); + auto data = + Artifact::ObjectInfo{ArtifactDigest{*digest}, ObjectType::File} + .ToString(); logger_.Emit(LogLevel::Debug, "Adding entry for key {} as {}", key.Id().ToString(), diff --git a/src/buildtool/build_engine/target_map/target_map.cpp b/src/buildtool/build_engine/target_map/target_map.cpp index e3f203a9..35f38588 100644 --- a/src/buildtool/build_engine/target_map/target_map.cpp +++ b/src/buildtool/build_engine/target_map/target_map.cpp @@ -536,9 +536,7 @@ void withDependencies( } blobs.emplace_back(data->String()); return ExpressionPtr{ArtifactDescription{ - {HashFunction::ComputeBlobHash(data->String()).HexString(), - data->String().size()}, - ObjectType::File}}; + ArtifactDigest::Create(data->String()), ObjectType::File}}; }}, {"TREE", [&trees](auto&& eval, auto const& expr, auto const& env) { diff --git a/src/buildtool/common/TARGETS b/src/buildtool/common/TARGETS index 5d06723a..950f6347 100644 --- a/src/buildtool/common/TARGETS +++ b/src/buildtool/common/TARGETS @@ -35,6 +35,7 @@ [ "bazel_types" , ["src/buildtool/crypto", "hash_function"] , ["src/buildtool/file_system", "object_type"] + , ["src/buildtool/compatibility", "compatibility"] , ["src/utils/cpp", "type_safe_arithmetic"] , ["src/utils/cpp", "hash_combine"] , ["@", "json", "", "json"] diff --git a/src/buildtool/common/artifact.cpp b/src/buildtool/common/artifact.cpp index fc3c5b6e..0ff89c89 100644 --- a/src/buildtool/common/artifact.cpp +++ b/src/buildtool/common/artifact.cpp @@ -19,6 +19,7 @@ auto Artifact::ObjectInfo::LiberalFromString(std::string const& s) noexcept std::getline(iss, type, ']'); } auto size = static_cast<std::size_t>(std::atol(size_str.c_str())); - return Artifact::ObjectInfo{ArtifactDigest{id, size}, - FromChar(*type.c_str())}; + auto const& object_type = FromChar(*type.c_str()); + return Artifact::ObjectInfo{ + ArtifactDigest{id, size, IsTreeObject(object_type)}, object_type}; } diff --git a/src/buildtool/common/artifact.hpp b/src/buildtool/common/artifact.hpp index 3f68a351..a073b0d7 100644 --- a/src/buildtool/common/artifact.hpp +++ b/src/buildtool/common/artifact.hpp @@ -63,8 +63,10 @@ class Artifact { } try { std::size_t size = std::stoul(size_str); - return ObjectInfo{ArtifactDigest{id, size}, - FromChar(*type.c_str())}; + auto const& object_type = FromChar(*type.c_str()); + return ObjectInfo{ + ArtifactDigest{id, size, IsTreeObject(object_type)}, + object_type}; } catch (std::out_of_range const& e) { Logger::Log(LogLevel::Error, "size raised out_of_range exception."); @@ -79,10 +81,12 @@ class Artifact { -> std::optional<ObjectInfo> { if (j.is_object() and j["id"].is_string() and j["size"].is_number() and j["type"].is_string()) { - return ObjectInfo{ - ArtifactDigest{j["id"].get<std::string>(), - j["size"].get<std::size_t>()}, - FromChar(*(j["type"].get<std::string>().c_str()))}; + auto const& object_type = + FromChar(*(j["type"].get<std::string>().c_str())); + return ObjectInfo{ArtifactDigest{j["id"].get<std::string>(), + j["size"].get<std::size_t>(), + IsTreeObject(object_type)}, + object_type}; } return std::nullopt; } @@ -168,7 +172,8 @@ class Artifact { std::size_t size, ObjectType type, std::optional<std::string> const& repo) noexcept -> Artifact { - return Artifact{id, {hash, size}, type, false, repo}; + return Artifact{ + id, {hash, size, IsTreeObject(type)}, type, false, repo}; } [[nodiscard]] static auto CreateActionArtifact( diff --git a/src/buildtool/common/artifact_description.hpp b/src/buildtool/common/artifact_description.hpp index 81f7780e..923be83f 100644 --- a/src/buildtool/common/artifact_description.hpp +++ b/src/buildtool/common/artifact_description.hpp @@ -272,8 +272,10 @@ class ArtifactDescription { }); if (blob_id.has_value() and size.has_value() and file_type.has_value() and file_type->size() == 1) { - return ArtifactDescription{ArtifactDigest{*blob_id, *size}, - FromChar((*file_type)[0])}; + auto const& object_type = FromChar((*file_type)[0]); + return ArtifactDescription{ + ArtifactDigest{*blob_id, *size, IsTreeObject(object_type)}, + object_type}; } return std::nullopt; } diff --git a/src/buildtool/common/artifact_digest.hpp b/src/buildtool/common/artifact_digest.hpp index 92bbde92..fdb4648e 100644 --- a/src/buildtool/common/artifact_digest.hpp +++ b/src/buildtool/common/artifact_digest.hpp @@ -6,54 +6,78 @@ #include "gsl-lite/gsl-lite.hpp" #include "src/buildtool/common/bazel_types.hpp" +#include "src/buildtool/compatibility/native_support.hpp" #include "src/buildtool/crypto/hash_function.hpp" +#include "src/buildtool/file_system/object_type.hpp" #include "src/utils/cpp/hash_combine.hpp" -// Wrapper for bazel_re::Digest. Can be implicitly cast to bazel_re::Digest. -// Provides getter for size with convenient non-protobuf type. +// Provides getter for size with convenient non-protobuf type. Contains a +// unprefixed hex string as hash. For communication with the exeution API it can +// be cast to bazel_re::Digest which is the wire format that contains prefixed +// hashes in native mode. class ArtifactDigest { public: ArtifactDigest() noexcept = default; - explicit ArtifactDigest(bazel_re::Digest digest) noexcept + + explicit ArtifactDigest(bazel_re::Digest const& digest) noexcept : size_{gsl::narrow<std::size_t>(digest.size_bytes())}, - digest_{std::move(digest)} {} - ArtifactDigest(std::string hash, std::size_t size) noexcept - : size_{size}, digest_{CreateBazelDigest(std::move(hash), size)} {} + hash_{NativeSupport::Unprefix(digest.hash())}, + is_tree_{NativeSupport::IsTree(digest.hash())} {} + + ArtifactDigest(std::string hash, std::size_t size, bool is_tree) noexcept + : size_{size}, hash_{std::move(hash)}, is_tree_{is_tree} { + gsl_ExpectsAudit(not NativeSupport::IsPrefixed(hash_)); + } [[nodiscard]] auto hash() const& noexcept -> std::string const& { - return digest_.hash(); + return hash_; } [[nodiscard]] auto hash() && noexcept -> std::string { - return std::move(*digest_.mutable_hash()); + return std::move(hash_); } [[nodiscard]] auto size() const noexcept -> std::size_t { return size_; } + [[nodiscard]] auto is_tree() const noexcept -> bool { return is_tree_; } + // NOLINTNEXTLINE allow implicit casts - [[nodiscard]] operator bazel_re::Digest const &() const& { return digest_; } - // NOLINTNEXTLINE allow implicit casts - [[nodiscard]] operator bazel_re::Digest() && { return std::move(digest_); } + [[nodiscard]] operator bazel_re::Digest() const { + return CreateBazelDigest(hash_, size_, is_tree_); + } [[nodiscard]] auto operator==(ArtifactDigest const& other) const -> bool { return std::equal_to<bazel_re::Digest>{}(*this, other); } + template <ObjectType kType = ObjectType::File> [[nodiscard]] static auto Create(std::string const& content) noexcept -> ArtifactDigest { - return ArtifactDigest{ - HashFunction::ComputeBlobHash(content).HexString(), content.size()}; + if constexpr (kType == ObjectType::Tree) { + return ArtifactDigest{ + HashFunction::ComputeTreeHash(content).HexString(), + content.size(), + /*is_tree=*/true}; + } + else { + return ArtifactDigest{ + HashFunction::ComputeBlobHash(content).HexString(), + content.size(), + /*is_tree=*/false}; + } } private: std::size_t size_{}; - bazel_re::Digest digest_{}; + std::string hash_{}; + bool is_tree_{}; - [[nodiscard]] static auto CreateBazelDigest(std::string&& hash, - std::size_t size) + [[nodiscard]] static auto CreateBazelDigest(std::string const& hash, + std::size_t size, + bool is_tree) -> bazel_re::Digest { bazel_re::Digest d; - d.set_hash(std::move(hash)); + d.set_hash(NativeSupport::Prefix(hash, is_tree)); d.set_size_bytes(gsl::narrow<google::protobuf::int64>(size)); return d; } @@ -67,6 +91,7 @@ struct hash<ArtifactDigest> { std::size_t seed{}; hash_combine(&seed, digest.hash()); hash_combine(&seed, digest.size()); + hash_combine(&seed, digest.is_tree()); return seed; } }; diff --git a/src/buildtool/common/artifact_factory.hpp b/src/buildtool/common/artifact_factory.hpp index e3ef2d0c..9021f27c 100644 --- a/src/buildtool/common/artifact_factory.hpp +++ b/src/buildtool/common/artifact_factory.hpp @@ -45,7 +45,8 @@ class ArtifactFactory { std::string const& blob_id, std::size_t size, ObjectType type = ObjectType::File) noexcept -> nlohmann::json { - return ArtifactDescription{ArtifactDigest{blob_id, size}, type} + return ArtifactDescription{ + ArtifactDigest{blob_id, size, IsTreeObject(type)}, type} .ToJson(); } diff --git a/src/buildtool/common/repository_config.cpp b/src/buildtool/common/repository_config.cpp index ba45052a..eb41acaa 100644 --- a/src/buildtool/common/repository_config.cpp +++ b/src/buildtool/common/repository_config.cpp @@ -30,7 +30,7 @@ auto RepositoryConfig::RepositoryKey(std::string const& repo) const noexcept if (auto graph = BuildGraphForRepository(unique)) { auto& cas = LocalCAS<ObjectType::File>::Instance(); if (auto digest = cas.StoreBlobFromBytes(graph->dump(2))) { - return digest->hash(); + return ArtifactDigest{*digest}.hash(); } } return std::nullopt; diff --git a/src/buildtool/execution_api/local/local_ac.hpp b/src/buildtool/execution_api/local/local_ac.hpp index 08f384d8..c9659494 100644 --- a/src/buildtool/execution_api/local/local_ac.hpp +++ b/src/buildtool/execution_api/local/local_ac.hpp @@ -27,12 +27,14 @@ class LocalAC { auto bytes = result.SerializeAsString(); auto digest = cas_->StoreBlobFromBytes(bytes); return (digest and file_store_.AddFromBytes( - action_id.hash(), digest->SerializeAsString())); + NativeSupport::Unprefix(action_id.hash()), + digest->SerializeAsString())); } [[nodiscard]] auto CachedResult(bazel_re::Digest const& action_id) const noexcept -> std::optional<bazel_re::ActionResult> { - auto entry_path = file_store_.GetPath(action_id.hash()); + auto entry_path = + file_store_.GetPath(NativeSupport::Unprefix(action_id.hash())); bazel_re::Digest digest{}; auto const entry = FileSystemManager::ReadFile(entry_path, ObjectType::File); diff --git a/src/buildtool/execution_api/local/local_api.hpp b/src/buildtool/execution_api/local/local_api.hpp index 03f116a8..20886e5a 100644 --- a/src/buildtool/execution_api/local/local_api.hpp +++ b/src/buildtool/execution_api/local/local_api.hpp @@ -140,7 +140,7 @@ class LocalApi final : public IExecutionApi { } if (tree_map_->AddTree(*digest, std::move(tree))) { - return ArtifactDigest{std::move(*digest)}; + return ArtifactDigest{*digest}; } return std::nullopt; } diff --git a/src/buildtool/execution_api/local/local_cas.hpp b/src/buildtool/execution_api/local/local_cas.hpp index f8efbb6a..310a3011 100644 --- a/src/buildtool/execution_api/local/local_cas.hpp +++ b/src/buildtool/execution_api/local/local_cas.hpp @@ -41,11 +41,12 @@ class LocalCAS { [[nodiscard]] auto BlobPath(bazel_re::Digest const& digest) const noexcept -> std::optional<std::filesystem::path> { - auto blob_path = file_store_.GetPath(digest.hash()); + auto id = NativeSupport::Unprefix(digest.hash()); + auto blob_path = file_store_.GetPath(id); if (FileSystemManager::IsFile(blob_path)) { return blob_path; } - logger_.Emit(LogLevel::Debug, "Blob not found {}", digest.hash()); + logger_.Emit(LogLevel::Debug, "Blob not found {}", id); return std::nullopt; } @@ -90,7 +91,8 @@ class LocalCAS { -> std::optional<bazel_re::Digest> { auto digest = CreateDigest(data); if (digest) { - if (StoreBlobData(digest->hash(), data, is_owner)) { + if (StoreBlobData( + NativeSupport::Unprefix(digest->hash()), data, is_owner)) { return digest; } logger_.Emit( diff --git a/src/buildtool/execution_engine/executor/executor.hpp b/src/buildtool/execution_engine/executor/executor.hpp index 9e83129a..721d4896 100644 --- a/src/buildtool/execution_engine/executor/executor.hpp +++ b/src/buildtool/execution_engine/executor/executor.hpp @@ -221,9 +221,7 @@ class ExecutorImpl { if (not content.has_value()) { return std::nullopt; } - auto digest = - ArtifactDigest{HashFunction::ComputeBlobHash(*content).HexString(), - content->size()}; + auto digest = ArtifactDigest::Create(*content); if (not api->Upload( BlobContainer{{BazelBlob{digest, std::move(*content)}}})) { return std::nullopt; diff --git a/src/buildtool/file_system/file_root.hpp b/src/buildtool/file_system/file_root.hpp index 747ca896..872ae1ff 100644 --- a/src/buildtool/file_system/file_root.hpp +++ b/src/buildtool/file_system/file_root.hpp @@ -399,6 +399,7 @@ class FileRoot { } // Create LOCAL or KNOWN artifact. Does not check existence for LOCAL. + // `file_path` must reference a blob. [[nodiscard]] auto ToArtifactDescription( std::filesystem::path const& file_path, std::string const& repository) const noexcept @@ -412,11 +413,14 @@ class FileRoot { auto compatible_hash = Compatibility::RegisterGitEntry( entry->Hash(), *entry->Blob(), repository); return ArtifactDescription{ - ArtifactDigest{compatible_hash, *entry->Size()}, + ArtifactDigest{compatible_hash, + *entry->Size(), + /*is_tree=*/false}, entry->Type()}; } return ArtifactDescription{ - ArtifactDigest{entry->Hash(), *entry->Size()}, + ArtifactDigest{ + entry->Hash(), *entry->Size(), /*is_tree=*/false}, entry->Type(), repository}; } diff --git a/src/buildtool/graph_traverser/graph_traverser.hpp b/src/buildtool/graph_traverser/graph_traverser.hpp index c00fe61b..e61a7280 100644 --- a/src/buildtool/graph_traverser/graph_traverser.hpp +++ b/src/buildtool/graph_traverser/graph_traverser.hpp @@ -261,8 +261,7 @@ class GraphTraverser { std::vector<std::string> const& blobs) const noexcept -> bool { BlobContainer container; for (auto const& blob : blobs) { - auto digest = ArtifactDigest{ - HashFunction::ComputeBlobHash(blob).HexString(), blob.size()}; + auto digest = ArtifactDigest::Create(blob); Logger::Log(LogLevel::Trace, [&]() { return fmt::format( "Uploaded blob {}, its digest has id {} and size {}.", |