Cache parsing results in PlatformMappingValue.
There will typically only be a single instance of PlatformMappingValue in a single command but it will be used for several configurations. Avoid re-parsing the mappings for each configuration by transiently caching the parsing results.
RELNOTES: None
package com.google.devtools.build.lib.skyframe;
import com.google.common.base.Preconditions;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Interner;
@@ -36,6 +38,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.ExecutionException;
import javax.annotation.Nullable;
/**
@@ -132,6 +135,7 @@ public final class PlatformMappingValue implements SkyValue {
private final Map<Label, Collection<String>> platformsToFlags;
private final Map<Collection<String>, Label> flagsToPlatforms;
+ private final transient Cache<Collection<String>, OptionsParsingResult> parserCache;
/**
* Creates a new mapping value which will match on the given platforms (if a target platform is
@@ -147,6 +151,10 @@ public final class PlatformMappingValue implements SkyValue {
Map<Collection<String>, Label> flagsToPlatforms) {
this.platformsToFlags = platformsToFlags;
this.flagsToPlatforms = flagsToPlatforms;
+ this.parserCache =
+ CacheBuilder.newBuilder()
+ .initialCapacity(platformsToFlags.size() + flagsToPlatforms.size())
+ .build();
}
/**
@@ -197,13 +205,14 @@ public final class PlatformMappingValue implements SkyValue {
return original;
}
- OptionsParsingResult parsingResult =
- parse(platformsToFlags.get(targetPlatform), defaultBuildOptions);
- modifiedOptions = originalOptions.applyParsingResult(parsingResult);
+ modifiedOptions =
+ originalOptions.applyParsingResult(
+ parseWithCache(platformsToFlags.get(targetPlatform), defaultBuildOptions));
} else {
boolean mappingFound = false;
for (Map.Entry<Collection<String>, Label> flagsToPlatform : flagsToPlatforms.entrySet()) {
- if (originalOptions.matches(parse(flagsToPlatform.getKey(), defaultBuildOptions))) {
+ if (originalOptions.matches(
+ parseWithCache(flagsToPlatform.getKey(), defaultBuildOptions))) {
modifiedOptions = originalOptions.clone();
modifiedOptions.get(PlatformOptions.class).platforms =
ImmutableList.of(flagsToPlatform.getValue());
@@ -224,6 +233,15 @@ public final class PlatformMappingValue implements SkyValue {
BuildOptions.diffForReconstruction(defaultBuildOptions, modifiedOptions));
}
+ private OptionsParsingResult parseWithCache(
+ Collection<String> args, BuildOptions defaultBuildOptions) throws OptionsParsingException {
+ try {
+ return parserCache.get(args, () -> parse(args, defaultBuildOptions));
+ } catch (ExecutionException e) {
+ throw (OptionsParsingException) e.getCause();
+ }
+ }
+
private OptionsParsingResult parse(Iterable<String> args, BuildOptions defaultBuildOptions)
throws OptionsParsingException {
OptionsParser parser = OptionsParser.newOptionsParser(defaultBuildOptions.getFragmentClasses());
