summaryrefslogtreecommitdiff
path: root/src/buildtool/tree_structure/tree_structure_utils.cpp
diff options
context:
space:
mode:
authorMaksim Denisov <denisov.maksim@huawei.com>2025-01-15 12:30:53 +0100
committerMaksim Denisov <denisov.maksim@huawei.com>2025-01-21 09:58:36 +0100
commit58830989428eaf9151177abeb756f31c47755596 (patch)
tree18faea3d1dbe5a37fcda922ea1d6a65a43fdf14b /src/buildtool/tree_structure/tree_structure_utils.cpp
parentaa8635c6863646f5df78b54832f51db16aac25ba (diff)
downloadjustbuild-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.cpp75
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));
+}