Migrate `TransitiveInfoProviderEffectiveClassHelper` to caffeine.
PiperOrigin-RevId: 380632901
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 80c2fd0..eb9de23 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
@@ -1143,6 +1143,7 @@
srcs = ["TransitiveInfoProviderEffectiveClassHelper.java"],
deps = [
":transitive_info_provider",
+ "//third_party:caffeine",
"//third_party:guava",
],
)
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderEffectiveClassHelper.java b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderEffectiveClassHelper.java
index d572e82..4814a2f 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderEffectiveClassHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderEffectiveClassHelper.java
@@ -14,13 +14,11 @@
package com.google.devtools.build.lib.analysis;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Verify;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import java.util.LinkedHashSet;
+import static com.google.common.base.Preconditions.checkState;
+
+import com.github.benmanes.caffeine.cache.Caffeine;
+import com.github.benmanes.caffeine.cache.LoadingCache;
+import com.google.common.collect.Sets;
import java.util.Set;
/**
@@ -31,58 +29,45 @@
* provider implements multiple TransitiveInfoProvider interfaces, prefer the explicit put builder
* methods.
*/
-class TransitiveInfoProviderEffectiveClassHelper {
+final class TransitiveInfoProviderEffectiveClassHelper {
private TransitiveInfoProviderEffectiveClassHelper() {}
private static final LoadingCache<
Class<? extends TransitiveInfoProvider>, Class<? extends TransitiveInfoProvider>>
- EFFECTIVE_PROVIDER_CLASS_CACHE =
- CacheBuilder.newBuilder()
- .build(
- new CacheLoader<
- Class<? extends TransitiveInfoProvider>,
- Class<? extends TransitiveInfoProvider>>() {
+ effectiveProviderClassCache =
+ Caffeine.newBuilder()
+ .build(TransitiveInfoProviderEffectiveClassHelper::findEffectiveProviderClass);
- private Set<Class<? extends TransitiveInfoProvider>> getDirectImplementations(
- Class<? extends TransitiveInfoProvider> providerClass) {
- Set<Class<? extends TransitiveInfoProvider>> result = new LinkedHashSet<>();
- for (Class<?> clazz : providerClass.getInterfaces()) {
- if (TransitiveInfoProvider.class.equals(clazz)) {
- result.add(providerClass);
- } else if (TransitiveInfoProvider.class.isAssignableFrom(clazz)) {
- result.addAll(
- getDirectImplementations(
- clazz.asSubclass(TransitiveInfoProvider.class)));
- }
- }
+ private static Class<? extends TransitiveInfoProvider> findEffectiveProviderClass(
+ Class<? extends TransitiveInfoProvider> providerClass) {
+ Set<Class<? extends TransitiveInfoProvider>> result = getDirectImplementations(providerClass);
+ checkState(
+ result.size() == 1,
+ "Effective provider class for %s is ambiguous (%s), specify explicitly.",
+ providerClass,
+ result);
+ return result.iterator().next();
+ }
- Class<?> superclass = providerClass.getSuperclass();
- if (superclass != null
- && TransitiveInfoProvider.class.isAssignableFrom(superclass)) {
- result.addAll(
- getDirectImplementations(
- superclass.asSubclass(TransitiveInfoProvider.class)));
- }
- return result;
- }
+ private static Set<Class<? extends TransitiveInfoProvider>> getDirectImplementations(
+ Class<? extends TransitiveInfoProvider> providerClass) {
+ Set<Class<? extends TransitiveInfoProvider>> result = Sets.newLinkedHashSetWithExpectedSize(1);
+ for (Class<?> clazz : providerClass.getInterfaces()) {
+ if (TransitiveInfoProvider.class.equals(clazz)) {
+ result.add(providerClass);
+ } else if (TransitiveInfoProvider.class.isAssignableFrom(clazz)) {
+ result.addAll(getDirectImplementations(clazz.asSubclass(TransitiveInfoProvider.class)));
+ }
+ }
- @Override
- public Class<? extends TransitiveInfoProvider> load(
- Class<? extends TransitiveInfoProvider> providerClass) {
- Set<Class<? extends TransitiveInfoProvider>> result =
- getDirectImplementations(providerClass);
- Verify.verify(!result.isEmpty()); // impossible
- Preconditions.checkState(
- result.size() == 1,
- "Effective provider class for %s is ambiguous (%s), specify explicitly.",
- providerClass,
- Joiner.on(',').join(result));
- return result.iterator().next();
- }
- });
+ Class<?> superclass = providerClass.getSuperclass();
+ if (superclass != null && TransitiveInfoProvider.class.isAssignableFrom(superclass)) {
+ result.addAll(getDirectImplementations(superclass.asSubclass(TransitiveInfoProvider.class)));
+ }
+ return result;
+ }
- // TODO(arielb): see if these can be made private?
@SuppressWarnings("unchecked")
static <T extends TransitiveInfoProvider> Class<T> get(T provider) {
return get((Class<T>) provider.getClass());
@@ -90,6 +75,6 @@
@SuppressWarnings("unchecked")
static <T extends TransitiveInfoProvider> Class<T> get(Class<T> providerClass) {
- return (Class<T>) EFFECTIVE_PROVIDER_CLASS_CACHE.getUnchecked(providerClass);
+ return (Class<T>) effectiveProviderClassCache.get(providerClass);
}
}