summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/build_engine/target_map/built_in_rules.cpp4
-rw-r--r--src/buildtool/build_engine/target_map/target_cache.cpp9
-rw-r--r--src/buildtool/build_engine/target_map/target_map.cpp4
-rw-r--r--src/buildtool/common/TARGETS1
-rw-r--r--src/buildtool/common/artifact.cpp5
-rw-r--r--src/buildtool/common/artifact.hpp19
-rw-r--r--src/buildtool/common/artifact_description.hpp6
-rw-r--r--src/buildtool/common/artifact_digest.hpp59
-rw-r--r--src/buildtool/common/artifact_factory.hpp3
-rw-r--r--src/buildtool/common/repository_config.cpp2
-rw-r--r--src/buildtool/execution_api/local/local_ac.hpp6
-rw-r--r--src/buildtool/execution_api/local/local_api.hpp2
-rw-r--r--src/buildtool/execution_api/local/local_cas.hpp8
-rw-r--r--src/buildtool/execution_engine/executor/executor.hpp4
-rw-r--r--src/buildtool/file_system/file_root.hpp8
-rw-r--r--src/buildtool/graph_traverser/graph_traverser.hpp3
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 {}.",