From 2cfab6bdf859695b934187b6d847329895ecd324 Mon Sep 17 00:00:00 2001 From: Oliver Reiche Date: Thu, 13 Oct 2022 15:59:25 +0200 Subject: TargetResult: Serialise inner TargetResults flat Before this change, TargetResults that appear inside of other TargetResults (typically via value nodes) were serialised via the top-level serialisation function for TargetResults. While technically correct, it is rather inefficient as identical expressions from outer and inner TargetResults are not properly deduplicated and a deeply nested data structure is maintained. With this change, expressions of inner TargetResults are serialised in the context of outer TargetResults, resulting in a flat list of all transitively contained expressions with proper deduplication applied. As this serialisation of TargetResult is used in target-level cache entries, the new format is a breaking change to existing entries. Therefore, after switching to the new serialisation format introduced by this commit, users are required to clean their target-level cache. This also reverts commit d22adef666d704680ee74b35a46d530f6b6d5f15, "Recursively scan provided results for known artifacts". --- .../build_engine/expression/target_result.cpp | 52 +++++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) (limited to 'src/buildtool/build_engine/expression/target_result.cpp') diff --git a/src/buildtool/build_engine/expression/target_result.cpp b/src/buildtool/build_engine/expression/target_result.cpp index cfc8b1fe..33df5dfb 100644 --- a/src/buildtool/build_engine/expression/target_result.cpp +++ b/src/buildtool/build_engine/expression/target_result.cpp @@ -138,8 +138,28 @@ auto SerializeTargetResultWithReplacement( } else if (expr->IsResult()) { provided_results->emplace_back(id); - json = SerializeTargetResultWithReplacement(expr->Result(), - replacements); + auto const& result = expr->Result(); + auto artifact_stage = SerializeExpression(nodes, + provided_artifacts, + provided_nodes, + provided_results, + result.artifact_stage, + replacements); + auto runfiles = SerializeExpression(nodes, + provided_artifacts, + provided_nodes, + provided_results, + result.runfiles, + replacements); + auto provides = SerializeExpression(nodes, + provided_artifacts, + provided_nodes, + provided_results, + result.provides, + replacements); + json = nlohmann::json({{"artifact_stage", artifact_stage}, + {"runfiles", runfiles}, + {"provides", provides}}); } else if (expr->IsArtifact()) { provided_artifacts->emplace_back(id); @@ -217,11 +237,29 @@ auto SerializeTargetResultWithReplacement( return ExpressionPtr{nullptr}; } if (provided_results.contains(id)) { - auto result = TargetResult::FromJson(json); - if (result) { - auto result_exp = ExpressionPtr{*result}; - sofar->emplace(id, result_exp); - return result_exp; + auto artifact_stage = DeserializeExpression(json["artifact_stage"], + nodes, + provided_artifacts, + provided_nodes, + provided_results, + sofar); + auto runfiles = DeserializeExpression(json["runfiles"], + nodes, + provided_artifacts, + provided_nodes, + provided_results, + sofar); + auto provides = DeserializeExpression(json["provides"], + nodes, + provided_artifacts, + provided_nodes, + provided_results, + sofar); + if (artifact_stage and runfiles and provides) { + return ExpressionPtr{TargetResult{std::move(artifact_stage), + std::move(provides), + std::move(runfiles), + /*is_cacheable=*/true}}; } return ExpressionPtr{nullptr}; } -- cgit v1.2.3