diff options
author | Maksim Denisov <denisov.maksim@huawei.com> | 2025-01-15 12:30:53 +0100 |
---|---|---|
committer | Maksim Denisov <denisov.maksim@huawei.com> | 2025-01-21 09:58:36 +0100 |
commit | 58830989428eaf9151177abeb756f31c47755596 (patch) | |
tree | 18faea3d1dbe5a37fcda922ea1d6a65a43fdf14b /src/buildtool/tree_structure/tree_structure_utils.cpp | |
parent | aa8635c6863646f5df78b54832f51db16aac25ba (diff) | |
download | justbuild-58830989428eaf9151177abeb756f31c47755596.tar.gz |
TreeStructureUtils: implement local computation of tree structure
Diffstat (limited to 'src/buildtool/tree_structure/tree_structure_utils.cpp')
-rw-r--r-- | src/buildtool/tree_structure/tree_structure_utils.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/buildtool/tree_structure/tree_structure_utils.cpp b/src/buildtool/tree_structure/tree_structure_utils.cpp index 7cc04b6f..f09d627b 100644 --- a/src/buildtool/tree_structure/tree_structure_utils.cpp +++ b/src/buildtool/tree_structure/tree_structure_utils.cpp @@ -31,6 +31,9 @@ #include "src/buildtool/common/repository_config.hpp" #include "src/buildtool/crypto/hash_function.hpp" #include "src/buildtool/execution_api/git/git_api.hpp" +#include "src/buildtool/execution_api/local/config.hpp" +#include "src/buildtool/execution_api/local/context.hpp" +#include "src/buildtool/execution_api/local/local_api.hpp" #include "src/buildtool/file_system/file_system_manager.hpp" #include "src/buildtool/file_system/git_repo.hpp" #include "src/buildtool/file_system/object_type.hpp" @@ -236,3 +239,75 @@ auto TreeStructureUtils::ExportFromGit( return git_api.RetrieveToCas({Artifact::ObjectInfo{tree, ObjectType::Tree}}, target_api); } + +auto TreeStructureUtils::ComputeStructureLocally( + ArtifactDigest const& tree, + std::vector<std::filesystem::path> const& known_repositories, + StorageConfig const& storage_config, + gsl::not_null<std::mutex*> const& tagging_lock) + -> expected<std::optional<ArtifactDigest>, std::string> { + if (not ProtocolTraits::IsNative(tree.GetHashType()) or not tree.IsTree()) { + return unexpected{fmt::format("Not a git tree: {}", tree.hash())}; + } + + if (not ProtocolTraits::IsNative(storage_config.hash_function.GetType())) { + return unexpected{fmt::format("Not a native storage config")}; + } + + auto const storage = Storage::Create(&storage_config); + LocalExecutionConfig const dummy_exec_config{}; + LocalContext const local_context{.exec_config = &dummy_exec_config, + .storage_config = &storage_config, + .storage = &storage}; + LocalApi const local_api{&local_context}; + + // First check the result is in cache already: + TreeStructureCache const tree_structure_cache{&storage_config}; + if (auto const from_cache = tree_structure_cache.Get(tree)) { + auto to_git = + ImportToGit(*from_cache, local_api, storage_config, tagging_lock); + if (not to_git.has_value()) { + return unexpected{fmt::format("While importing {} to git:\n{}", + from_cache->hash(), + std::move(to_git).error())}; + } + return std::make_optional<ArtifactDigest>(std::move(to_git).value()); + } + + // If the tree is not in the storage, it must be present in git: + if (not storage.CAS().TreePath(tree).has_value()) { + auto in_cas = ExportFromGit(tree, known_repositories, local_api); + if (not in_cas.has_value()) { + return unexpected{ + fmt::format("While exporting {} from git to CAS:\n{}", + tree.hash(), + std::move(in_cas).error())}; + } + + // If the tree hasn't been found neither in CAS, nor in git, there's + // nothing else to do: + if (not storage.CAS().TreePath(tree).has_value()) { + return std::optional<ArtifactDigest>{}; + } + } + + // Compute tree structure and add it to the storage and cache: + auto tree_structure = Compute(tree, storage, tree_structure_cache); + if (not tree_structure) { + return unexpected{ + fmt::format("Failed to compute tree structure of {}:\n{}", + tree.hash(), + std::move(tree_structure).error())}; + } + + // Import the result to git: + auto to_git = + ImportToGit(*tree_structure, local_api, storage_config, tagging_lock); + if (not to_git.has_value()) { + return unexpected{fmt::format( + "While importing the resulting tree structure {} to git:\n{}", + tree_structure->hash(), + std::move(to_git).error())}; + } + return std::make_optional<ArtifactDigest>(*std::move(tree_structure)); +} |