Cache the invocation of TestTrimmingTransition.applyTransition.
This implementation uses the pre-existing BuildOptionsCache class inside TestTrimmingTransition to resolve the performance issue with --trim_test_configuration on longwide. (Previous attempts used a SkyFunction, a custom cache at ConfigurationResolve, or a custom cache at TestTrimmingTransition.)
PiperOrigin-RevId: 329607319
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BUILD b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
index 1a26394..f367071 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
@@ -2270,6 +2270,7 @@
srcs = ["test/TestTrimmingTransitionFactory.java"],
deps = [
":config/build_options",
+ ":config/build_options_cache",
":config/fragment_options",
":config/transitions/no_transition",
":config/transitions/patch_transition",
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/test/TestTrimmingTransitionFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/test/TestTrimmingTransitionFactory.java
index a759b25..3faac3c 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/test/TestTrimmingTransitionFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/test/TestTrimmingTransitionFactory.java
@@ -15,6 +15,7 @@
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
+import com.google.devtools.build.lib.analysis.config.BuildOptionsCache;
import com.google.devtools.build.lib.analysis.config.BuildOptionsView;
import com.google.devtools.build.lib.analysis.config.FragmentOptions;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
@@ -42,6 +43,14 @@
public enum TestTrimmingTransition implements PatchTransition {
INSTANCE;
+ // This cache is to prevent major slowdowns when using --trim_test_configuration. This
+ // transition is always invoked on every target in the top-level invocation. Thus, a wide
+ // invocation, like //..., will cause the transition to be invoked on a large number of targets
+ // leading to significant performance degradation. (Notably, the transition itself is somewhat
+ // fast; however, the post-processing of the BuildOptions results into a BuildConfiguration
+ // takes a significant amount of time).
+ private static final BuildOptionsCache<Integer> cache = new BuildOptionsCache<>();
+
@Override
public ImmutableSet<Class<? extends FragmentOptions>> requiresOptionFragments() {
return ImmutableSet.of(TestOptions.class);
@@ -58,9 +67,15 @@
// nothing to do, trimming is disabled
return originalOptions.underlying();
}
- return originalOptions.underlying().toBuilder()
- .removeFragmentOptions(TestOptions.class)
- .build();
+ return cache.applyTransition(
+ originalOptions,
+ // The transition uses no non-BuildOptions arguments
+ 0,
+ () -> {
+ return originalOptions.underlying().toBuilder()
+ .removeFragmentOptions(TestOptions.class)
+ .build();
+ });
}
}
@@ -75,7 +90,7 @@
}
Set<String> referencedTestOptions =
- new LinkedHashSet<String>(ruleClass.getOptionReferenceFunction().apply(rule));
+ new LinkedHashSet<>(ruleClass.getOptionReferenceFunction().apply(rule));
referencedTestOptions.retainAll(TEST_OPTIONS);
if (!referencedTestOptions.isEmpty()) {
// Test-option-referencing config_setting; no need to trim here.