diff options
author | Maksim Denisov <denisov.maksim@huawei.com> | 2024-07-23 15:07:04 +0200 |
---|---|---|
committer | Maksim Denisov <denisov.maksim@huawei.com> | 2024-08-30 17:17:09 +0200 |
commit | d9ff1b6073330c304fecdf77a16702a0df5faeac (patch) | |
tree | f64cd1660b21474811a52797344b3e012f6f9431 /src | |
parent | 0ba7060660fdcf095556be0e2837cb785ccdea9d (diff) | |
download | justbuild-d9ff1b6073330c304fecdf77a16702a0df5faeac.tar.gz |
Replace bazel_re::Digest in LargeObjectCAS
...with ArtifactDigest.
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/storage/large_object_cas.hpp | 26 | ||||
-rw-r--r-- | src/buildtool/storage/large_object_cas.tpp | 53 | ||||
-rw-r--r-- | src/buildtool/storage/local_cas.hpp | 71 | ||||
-rw-r--r-- | src/buildtool/storage/local_cas.tpp | 32 |
4 files changed, 109 insertions, 73 deletions
diff --git a/src/buildtool/storage/large_object_cas.hpp b/src/buildtool/storage/large_object_cas.hpp index 971b943d..8a6986ee 100644 --- a/src/buildtool/storage/large_object_cas.hpp +++ b/src/buildtool/storage/large_object_cas.hpp @@ -21,7 +21,7 @@ #include <utility> #include <vector> -#include "src/buildtool/common/bazel_types.hpp" +#include "src/buildtool/common/artifact_digest.hpp" #include "src/buildtool/file_system/file_storage.hpp" #include "src/buildtool/file_system/object_type.hpp" #include "src/buildtool/storage/config.hpp" @@ -123,16 +123,16 @@ class LargeObjectCAS final { /// \brief Get the path to a large entry in the storage. /// \param digest The digest of a large object. /// \returns Path to the large entry if in the storage. - [[nodiscard]] auto GetEntryPath(bazel_re::Digest const& digest) - const noexcept -> std::optional<std::filesystem::path>; + [[nodiscard]] auto GetEntryPath(ArtifactDigest const& digest) const noexcept + -> std::optional<std::filesystem::path>; /// \brief Split an object from the main CAS into chunks. If the object had /// been split before, it would not get split again. /// \param digest The digest of the object to be split. /// \return A set of chunks the resulting object is composed of /// or an error on failure. - [[nodiscard]] auto Split(bazel_re::Digest const& digest) const noexcept - -> expected<std::vector<bazel_re::Digest>, LargeObjectError>; + [[nodiscard]] auto Split(ArtifactDigest const& digest) const noexcept + -> expected<std::vector<ArtifactDigest>, LargeObjectError>; /// \brief Splice an object based on the reconstruction rules from the /// storage. This method doesn't check whether the result of splicing is @@ -140,7 +140,7 @@ class LargeObjectCAS final { /// \param digest The digest of the object to be spliced. /// \return A temporary directory that contains a single file /// "result" on success or an error on failure. - [[nodiscard]] auto TrySplice(bazel_re::Digest const& digest) const noexcept + [[nodiscard]] auto TrySplice(ArtifactDigest const& digest) const noexcept -> expected<LargeObject, LargeObjectError>; /// \brief Splice an object from parts. This method doesn't check whether @@ -149,8 +149,8 @@ class LargeObjectCAS final { /// \param parts Parts to be concatenated. /// \return A temporary directory that contains a single file /// "result" on success or an error on failure. - [[nodiscard]] auto Splice(bazel_re::Digest const& digest, - std::vector<bazel_re::Digest> const& parts) + [[nodiscard]] auto Splice(ArtifactDigest const& digest, + std::vector<ArtifactDigest> const& parts) const noexcept -> expected<LargeObject, LargeObjectError>; /// \brief Uplink large entry from this generation to latest LocalCAS @@ -167,7 +167,7 @@ class LargeObjectCAS final { [[nodiscard]] auto LocalUplink( LocalCAS<false> const& latest, LargeObjectCAS<false, kType> const& latest_large, - bazel_re::Digest const& digest) const noexcept -> bool; + ArtifactDigest const& digest) const noexcept -> bool; private: // By default, overwrite existing entries. Unless this is a generation @@ -185,16 +185,16 @@ class LargeObjectCAS final { /// \param digest The digest of a large object. /// \returns Parts the large object is composed of, if present in /// the storage. - [[nodiscard]] auto ReadEntry(bazel_re::Digest const& digest) const noexcept - -> std::optional<std::vector<bazel_re::Digest>>; + [[nodiscard]] auto ReadEntry(ArtifactDigest const& digest) const noexcept + -> std::optional<std::vector<ArtifactDigest>>; /// \brief Create a new entry description and add it to the storage. /// \param digest The digest of the result. /// \param parts Parts the resulting object is composed of. /// \returns True if the entry exists afterwards. [[nodiscard]] auto WriteEntry( - bazel_re::Digest const& digest, - std::vector<bazel_re::Digest> const& parts) const noexcept -> bool; + ArtifactDigest const& digest, + std::vector<ArtifactDigest> const& parts) const noexcept -> bool; }; #include "src/buildtool/storage/large_object_cas.tpp" diff --git a/src/buildtool/storage/large_object_cas.tpp b/src/buildtool/storage/large_object_cas.tpp index 5fbfee07..18c15ce6 100644 --- a/src/buildtool/storage/large_object_cas.tpp +++ b/src/buildtool/storage/large_object_cas.tpp @@ -23,7 +23,6 @@ #include "fmt/core.h" #include "nlohmann/json.hpp" #include "src/buildtool/compatibility/compatibility.hpp" -#include "src/buildtool/compatibility/native_support.hpp" #include "src/buildtool/file_system/file_system_manager.hpp" #include "src/buildtool/storage/file_chunker.hpp" #include "src/buildtool/storage/large_object_cas.hpp" @@ -36,10 +35,9 @@ inline constexpr std::size_t kSizeIndex = 1; template <bool kDoGlobalUplink, ObjectType kType> auto LargeObjectCAS<kDoGlobalUplink, kType>::GetEntryPath( - bazel_re::Digest const& digest) const noexcept + ArtifactDigest const& digest) const noexcept -> std::optional<std::filesystem::path> { - const std::string hash = NativeSupport::Unprefix(digest.hash()); - const std::filesystem::path file_path = file_store_.GetPath(hash); + const std::filesystem::path file_path = file_store_.GetPath(digest.hash()); if (FileSystemManager::IsFile(file_path)) { return file_path; } @@ -60,14 +58,14 @@ auto LargeObjectCAS<kDoGlobalUplink, kType>::GetEntryPath( template <bool kDoGlobalUplink, ObjectType kType> auto LargeObjectCAS<kDoGlobalUplink, kType>::ReadEntry( - bazel_re::Digest const& digest) const noexcept - -> std::optional<std::vector<bazel_re::Digest>> { + ArtifactDigest const& digest) const noexcept + -> std::optional<std::vector<ArtifactDigest>> { auto const file_path = GetEntryPath(digest); if (not file_path) { return std::nullopt; } - std::vector<bazel_re::Digest> parts; + std::vector<ArtifactDigest> parts; try { std::ifstream stream(*file_path); nlohmann::json j = nlohmann::json::parse(stream); @@ -77,8 +75,7 @@ auto LargeObjectCAS<kDoGlobalUplink, kType>::ReadEntry( auto hash = j_part.at(kHashIndex).template get<std::string>(); auto size = j_part.at(kSizeIndex).template get<std::size_t>(); - parts.emplace_back( - ArtifactDigest{std::move(hash), size, /*is_tree=*/false}); + parts.emplace_back(std::move(hash), size, /*is_tree=*/false); } } catch (...) { return std::nullopt; @@ -88,8 +85,8 @@ auto LargeObjectCAS<kDoGlobalUplink, kType>::ReadEntry( template <bool kDoGlobalUplink, ObjectType kType> auto LargeObjectCAS<kDoGlobalUplink, kType>::WriteEntry( - bazel_re::Digest const& digest, - std::vector<bazel_re::Digest> const& parts) const noexcept -> bool { + ArtifactDigest const& digest, + std::vector<ArtifactDigest> const& parts) const noexcept -> bool { if (GetEntryPath(digest)) { return true; } @@ -106,23 +103,18 @@ auto LargeObjectCAS<kDoGlobalUplink, kType>::WriteEntry( try { for (auto const& part : parts) { auto& j_part = j.emplace_back(); - - ArtifactDigest const a_digest(part); - j_part[kHashIndex] = a_digest.hash(); - j_part[kSizeIndex] = a_digest.size(); + j_part[kHashIndex] = part.hash(); + j_part[kSizeIndex] = part.size(); } } catch (...) { return false; } - - const auto hash = NativeSupport::Unprefix(digest.hash()); - return file_store_.AddFromBytes(hash, j.dump()); + return file_store_.AddFromBytes(digest.hash(), j.dump()); } template <bool kDoGlobalUplink, ObjectType kType> -auto LargeObjectCAS<kDoGlobalUplink, kType>::Split( - bazel_re::Digest const& digest) const noexcept - -> expected<std::vector<bazel_re::Digest>, LargeObjectError> { +auto LargeObjectCAS<kDoGlobalUplink, kType>::Split(ArtifactDigest const& digest) + const noexcept -> expected<std::vector<ArtifactDigest>, LargeObjectError> { if (auto large_entry = ReadEntry(digest)) { return std::move(*large_entry); } @@ -154,7 +146,7 @@ auto LargeObjectCAS<kDoGlobalUplink, kType>::Split( fmt::format("could not split {}", digest.hash())}}; } - std::vector<bazel_re::Digest> parts; + std::vector<ArtifactDigest> parts; try { while (auto chunk = chunker.NextChunk()) { auto part = local_cas_.StoreBlob(*chunk, /*is_executable=*/false); @@ -162,7 +154,7 @@ auto LargeObjectCAS<kDoGlobalUplink, kType>::Split( return unexpected{LargeObjectError{ LargeObjectErrorCode::Internal, "could not store a part."}}; } - parts.push_back(std::move(*part)); + parts.emplace_back(*std::move(part)); } } catch (...) { return unexpected{LargeObjectError{LargeObjectErrorCode::Internal, @@ -180,7 +172,7 @@ auto LargeObjectCAS<kDoGlobalUplink, kType>::Split( template <bool kDoGlobalUplink, ObjectType kType> auto LargeObjectCAS<kDoGlobalUplink, kType>::TrySplice( - bazel_re::Digest const& digest) const noexcept + ArtifactDigest const& digest) const noexcept -> expected<LargeObject, LargeObjectError> { auto parts = ReadEntry(digest); if (not parts) { @@ -193,8 +185,8 @@ auto LargeObjectCAS<kDoGlobalUplink, kType>::TrySplice( template <bool kDoGlobalUplink, ObjectType kType> auto LargeObjectCAS<kDoGlobalUplink, kType>::Splice( - bazel_re::Digest const& digest, - std::vector<bazel_re::Digest> const& parts) const noexcept + ArtifactDigest const& digest, + std::vector<ArtifactDigest> const& parts) const noexcept -> expected<LargeObject, LargeObjectError> { // Create temporary space for splicing: LargeObject large_object(storage_config_); @@ -236,7 +228,7 @@ auto LargeObjectCAS<kDoGlobalUplink, kType>::Splice( stream.close(); } catch (...) { return unexpected{LargeObjectError{LargeObjectErrorCode::Internal, - "an unknown error occured"}}; + "an unknown error occurred"}}; } return large_object; } @@ -247,7 +239,7 @@ template <bool kIsLocalGeneration> auto LargeObjectCAS<kDoGlobalUplink, kType>::LocalUplink( LocalCAS<false> const& latest, LargeObjectCAS<false, kType> const& latest_large, - bazel_re::Digest const& digest) const noexcept -> bool { + ArtifactDigest const& digest) const noexcept -> bool { // Check the large entry in the youngest generation: if (latest_large.GetEntryPath(digest)) { return true; @@ -274,9 +266,8 @@ auto LargeObjectCAS<kDoGlobalUplink, kType>::LocalUplink( if (not path) { return false; } - - const auto hash = NativeSupport::Unprefix(digest.hash()); - return latest_large.file_store_.AddFromFile(hash, *path, /*is_owner=*/true); + return latest_large.file_store_.AddFromFile( + digest.hash(), *path, /*is_owner=*/true); } #endif // INCLUDED_SRC_BUILDTOOL_STORAGE_LARGE_OBJECT_CAS_TPP diff --git a/src/buildtool/storage/local_cas.hpp b/src/buildtool/storage/local_cas.hpp index 3097780a..4fc11d4a 100644 --- a/src/buildtool/storage/local_cas.hpp +++ b/src/buildtool/storage/local_cas.hpp @@ -160,7 +160,17 @@ class LocalCAS { /// error code on failure. [[nodiscard]] auto SplitBlob(bazel_re::Digest const& digest) const noexcept -> expected<std::vector<bazel_re::Digest>, LargeObjectError> { - return cas_file_large_.Split(digest); + auto const a_digest = static_cast<ArtifactDigest>(digest); + auto split_result = cas_file_large_.Split(a_digest); + if (not split_result) { + return unexpected{std::move(split_result).error()}; + } + std::vector<bazel_re::Digest> result; + result.reserve(split_result->size()); + std::copy(split_result->begin(), + split_result->end(), + std::back_inserter(result)); + return result; } /// \brief Splice a blob from parts. @@ -173,8 +183,22 @@ class LocalCAS { std::vector<bazel_re::Digest> const& parts, bool is_executable) const noexcept -> expected<bazel_re::Digest, LargeObjectError> { - return is_executable ? Splice<ObjectType::Executable>(digest, parts) - : Splice<ObjectType::File>(digest, parts); + auto const a_digest = static_cast<ArtifactDigest>(digest); + std::vector<ArtifactDigest> a_parts; + a_parts.reserve(parts.size()); + std::transform( + parts.begin(), + parts.end(), + std::back_inserter(a_parts), + [](auto const& digest) { return ArtifactDigest{digest}; }); + auto splice_result = + is_executable ? Splice<ObjectType::Executable>(a_digest, a_parts) + : Splice<ObjectType::File>(a_digest, a_parts); + + if (not splice_result) { + return unexpected{std::move(splice_result).error()}; + } + return static_cast<bazel_re::Digest>(*splice_result); } /// \brief Obtain tree path from digest. @@ -192,7 +216,17 @@ class LocalCAS { /// error code on failure. [[nodiscard]] auto SplitTree(bazel_re::Digest const& digest) const noexcept -> expected<std::vector<bazel_re::Digest>, LargeObjectError> { - return cas_tree_large_.Split(digest); + auto const a_digest = static_cast<ArtifactDigest>(digest); + auto split_result = cas_tree_large_.Split(a_digest); + if (not split_result) { + return unexpected{std::move(split_result).error()}; + } + std::vector<bazel_re::Digest> result; + result.reserve(split_result->size()); + std::copy(split_result->begin(), + split_result->end(), + std::back_inserter(result)); + return result; } /// \brief Splice a tree from parts. @@ -203,7 +237,19 @@ class LocalCAS { [[nodiscard]] auto SpliceTree(bazel_re::Digest const& digest, std::vector<bazel_re::Digest> const& parts) const noexcept -> expected<bazel_re::Digest, LargeObjectError> { - return Splice<ObjectType::Tree>(digest, parts); + auto const a_digest = static_cast<ArtifactDigest>(digest); + std::vector<ArtifactDigest> a_parts; + a_parts.reserve(parts.size()); + std::transform( + parts.begin(), + parts.end(), + std::back_inserter(a_parts), + [](auto const& digest) { return ArtifactDigest{digest}; }); + auto splice_result = Splice<ObjectType::Tree>(a_digest, a_parts); + if (not splice_result) { + return unexpected{std::move(splice_result).error()}; + } + return static_cast<bazel_re::Digest>(*splice_result); } /// \brief Check whether all parts of the tree are in the storage. @@ -331,13 +377,13 @@ class LocalCAS { template <ObjectType kType, bool kIsLocalGeneration = not kDoGlobalUplink> requires(kIsLocalGeneration) - [[nodiscard]] auto TrySplice(bazel_re::Digest const& digest) const noexcept + [[nodiscard]] auto TrySplice(ArtifactDigest const& digest) const noexcept -> std::optional<LargeObject>; template <ObjectType kType> - [[nodiscard]] auto Splice(bazel_re::Digest const& digest, - std::vector<bazel_re::Digest> const& parts) - const noexcept -> expected<bazel_re::Digest, LargeObjectError>; + [[nodiscard]] auto Splice(ArtifactDigest const& digest, + std::vector<ArtifactDigest> const& parts) + const noexcept -> expected<ArtifactDigest, LargeObjectError>; }; #ifndef BOOTSTRAP_BUILD_TOOL @@ -353,10 +399,9 @@ auto LocalCAS<kDoGlobalUplink>::CheckTreeInvariant( template <bool kDoGlobalUplink> template <ObjectType kType> -auto LocalCAS<kDoGlobalUplink>::Splice( - bazel_re::Digest const& digest, - std::vector<bazel_re::Digest> const& parts) const noexcept - -> expected<bazel_re::Digest, LargeObjectError> { +auto LocalCAS<kDoGlobalUplink>::Splice(ArtifactDigest const& digest, + std::vector<ArtifactDigest> const& parts) + const noexcept -> expected<ArtifactDigest, LargeObjectError> { return unexpected{ LargeObjectError{LargeObjectErrorCode::Internal, "not allowed"}}; } diff --git a/src/buildtool/storage/local_cas.tpp b/src/buildtool/storage/local_cas.tpp index fb828617..7f44b0c2 100644 --- a/src/buildtool/storage/local_cas.tpp +++ b/src/buildtool/storage/local_cas.tpp @@ -59,7 +59,8 @@ auto LocalCAS<kDoGlobalUplink>::LocalUplinkBlob( : BlobPath(digest, is_executable); std::optional<LargeObject> spliced; if (not blob_path) { - spliced = TrySplice<ObjectType::File>(digest); + spliced = + TrySplice<ObjectType::File>(static_cast<ArtifactDigest>(digest)); blob_path = spliced ? std::optional{spliced->GetPath()} : std::nullopt; } if (not blob_path) { @@ -123,7 +124,7 @@ auto LocalCAS<kDoGlobalUplink>::LocalUplinkGitTree( auto tree_path = cas_tree_.BlobPath(a_digest); std::optional<LargeObject> spliced; if (not tree_path) { - spliced = TrySplice<ObjectType::Tree>(digest); + spliced = TrySplice<ObjectType::Tree>(a_digest); tree_path = spliced ? std::optional{spliced->GetPath()} : std::nullopt; } if (not tree_path) { @@ -219,7 +220,7 @@ auto LocalCAS<kDoGlobalUplink>::LocalUplinkBazelDirectory( auto dir_path = cas_tree_.BlobPath(a_digest); std::optional<LargeObject> spliced; if (not dir_path) { - spliced = TrySplice<ObjectType::Tree>(digest); + spliced = TrySplice<ObjectType::Tree>(a_digest); dir_path = spliced ? std::optional{spliced->GetPath()} : std::nullopt; } if (not dir_path) { @@ -280,21 +281,22 @@ template <ObjectType kType, bool kIsLocalGeneration> auto LocalCAS<kDoGlobalUplink>::LocalUplinkLargeObject( LocalGenerationCAS const& latest, bazel_re::Digest const& digest) const noexcept -> bool { + auto const a_digest = static_cast<ArtifactDigest>(digest); if constexpr (IsTreeObject(kType)) { return cas_tree_large_.LocalUplink( - latest, latest.cas_tree_large_, digest); + latest, latest.cas_tree_large_, a_digest); } else { return cas_file_large_.LocalUplink( - latest, latest.cas_file_large_, digest); + latest, latest.cas_file_large_, a_digest); } } template <bool kDoGlobalUplink> template <ObjectType kType, bool kIsLocalGeneration> requires(kIsLocalGeneration) -auto LocalCAS<kDoGlobalUplink>::TrySplice(bazel_re::Digest const& digest) - const noexcept -> std::optional<LargeObject> { +auto LocalCAS<kDoGlobalUplink>::TrySplice( + ArtifactDigest const& digest) const noexcept -> std::optional<LargeObject> { auto spliced = IsTreeObject(kType) ? cas_tree_large_.TrySplice(digest) : cas_file_large_.TrySplice(digest); return spliced and spliced->IsValid() ? std::optional{std::move(*spliced)} @@ -326,10 +328,9 @@ auto LocalCAS<kDoGlobalUplink>::CheckTreeInvariant( // Ensure all entries are in the storage: for (const auto& entry : *entries) { for (auto const& item : entry.second) { - bazel_re::Digest const digest = - ArtifactDigest(ToHexString(entry.first), - /*size_unknown=*/0ULL, - IsTreeObject(item.type)); + auto const digest = ArtifactDigest(ToHexString(entry.first), + /*size_unknown=*/0ULL, + IsTreeObject(item.type)); // To avoid splicing during search, large CASes are inspected first. bool const entry_exists = @@ -352,10 +353,9 @@ auto LocalCAS<kDoGlobalUplink>::CheckTreeInvariant( template <bool kDoGlobalUplink> template <ObjectType kType> -auto LocalCAS<kDoGlobalUplink>::Splice( - bazel_re::Digest const& digest, - std::vector<bazel_re::Digest> const& parts) const noexcept - -> expected<bazel_re::Digest, LargeObjectError> { +auto LocalCAS<kDoGlobalUplink>::Splice(ArtifactDigest const& digest, + std::vector<ArtifactDigest> const& parts) + const noexcept -> expected<ArtifactDigest, LargeObjectError> { static constexpr bool kIsTree = IsTreeObject(kType); static constexpr bool kIsExec = IsExecutableObject(kType); @@ -414,7 +414,7 @@ auto LocalCAS<kDoGlobalUplink>::Splice( auto const stored_digest = kIsTree ? StoreTree<kOwner>(file_path) : StoreBlob<kOwner>(file_path, kIsExec); if (stored_digest) { - return std::move(*stored_digest); + return ArtifactDigest{std::move(*stored_digest)}; } return unexpected{ LargeObjectError{LargeObjectErrorCode::Internal, |