Migrate uses of Guava's `MapMaker` to caffeine. PiperOrigin-RevId: 381007927
diff --git a/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetBuilder.java b/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetBuilder.java index 379b1ed..0e65b5d 100644 --- a/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetBuilder.java
@@ -16,15 +16,15 @@ import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.collect.Iterables.getOnlyElement; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; -import com.google.common.collect.MapMaker; import com.google.devtools.build.lib.collect.compacthashset.CompactHashSet; import com.google.devtools.build.lib.collect.nestedset.NestedSet.InterruptStrategy; import java.util.Set; -import java.util.concurrent.ConcurrentMap; /** * A builder for nested sets. @@ -190,8 +190,11 @@ return new NestedSet<>(order, direct, transitive, interruptStrategy); } - private static final ConcurrentMap<ImmutableList<?>, NestedSet<?>> immutableListCache = - new MapMaker().concurrencyLevel(16).weakKeys().makeMap(); + private static final LoadingCache<ImmutableList<?>, NestedSet<?>> stableOrderImmutableListCache = + Caffeine.newBuilder() + .initialCapacity(16) + .weakKeys() + .build(list -> new NestedSetBuilder<>(Order.STABLE_ORDER).addAll(list).build()); /** Creates a nested set from a given list of items. */ @SuppressWarnings("unchecked") @@ -199,15 +202,9 @@ if (Iterables.isEmpty(wrappedItems)) { return order.emptySet(); } else if (order == Order.STABLE_ORDER && wrappedItems instanceof ImmutableList) { - ImmutableList<E> wrappedList = (ImmutableList) wrappedItems; + ImmutableList<E> wrappedList = (ImmutableList<E>) wrappedItems; if (wrappedList.size() > 1) { - NestedSet<?> cached = immutableListCache.get(wrappedList); - if (cached != null) { - return (NestedSet<E>) cached; - } - NestedSet<E> built = new NestedSetBuilder<E>(order).addAll(wrappedList).build(); - immutableListCache.putIfAbsent(wrappedList, built); - return built; + return (NestedSet<E>) stableOrderImmutableListCache.get(wrappedList); } } return new NestedSetBuilder<E>(order).addAll(wrappedItems).build();
diff --git a/src/main/java/com/google/devtools/build/lib/profiler/memory/AllocationTracker.java b/src/main/java/com/google/devtools/build/lib/profiler/memory/AllocationTracker.java index b80228a..6bf1e3e7 100644 --- a/src/main/java/com/google/devtools/build/lib/profiler/memory/AllocationTracker.java +++ b/src/main/java/com/google/devtools/build/lib/profiler/memory/AllocationTracker.java
@@ -14,10 +14,11 @@ package com.google.devtools.build.lib.profiler.memory; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import com.google.common.base.Objects; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; -import com.google.common.collect.MapMaker; import com.google.devtools.build.lib.concurrent.ThreadSafety.ConditionallyThreadCompatible; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; import com.google.devtools.build.lib.packages.AspectClass; @@ -92,7 +93,8 @@ } } - private final Map<Object, AllocationSample> allocations = new MapMaker().weakKeys().makeMap(); + private final Cache<Object, AllocationSample> allocations = + Caffeine.newBuilder().weakKeys().build(); private final int samplePeriod; private final int sampleVariance; private boolean enabled = true; @@ -248,7 +250,7 @@ System.gc(); // Get loading phase memory for rules. - for (AllocationSample sample : allocations.values()) { + for (AllocationSample sample : allocations.asMap().values()) { RuleFunction rule = getRule(sample); if (rule != null) { RuleClass ruleClass = rule.getRuleClass(); @@ -258,7 +260,7 @@ } } // Get analysis phase memory for rules and aspects - for (AllocationSample sample : allocations.values()) { + for (AllocationSample sample : allocations.asMap().values()) { if (sample.ruleClass != null) { String key = sample.ruleClass.getKey(); RuleBytes ruleBytes = @@ -299,7 +301,7 @@ .setType(stringTable.get("memory")) .setUnit(stringTable.get("bytes")) .build()); - for (AllocationSample sample : allocations.values()) { + for (AllocationSample sample : allocations.asMap().values()) { // Skip empty callstacks if (sample.callstack.isEmpty()) { continue;
diff --git a/src/main/java/com/google/devtools/build/lib/profiler/memory/BUILD b/src/main/java/com/google/devtools/build/lib/profiler/memory/BUILD index 20971cd..eec2f89 100644 --- a/src/main/java/com/google/devtools/build/lib/profiler/memory/BUILD +++ b/src/main/java/com/google/devtools/build/lib/profiler/memory/BUILD
@@ -49,6 +49,7 @@ "//src/main/java/com/google/devtools/build/lib/packages", "//src/main/java/net/starlark/java/eval", "//src/main/java/net/starlark/java/syntax", + "//third_party:caffeine", "//third_party:guava", "//third_party:jsr305", "//third_party/allocation_instrumenter",
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactNestedSetFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactNestedSetFunction.java index 1e21a03..95e0154 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactNestedSetFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactNestedSetFunction.java
@@ -15,8 +15,9 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import com.google.common.base.Suppliers; -import com.google.common.collect.MapMaker; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.collect.nestedset.NestedSet; @@ -84,11 +85,11 @@ * Maps the NestedSets' underlying objects to the corresponding SkyKey. This is to avoid * re-creating SkyKey for the same nested set upon reevaluation because of e.g. a missing value. * - * <p>The map weakly references its values: when the ArtifactNestedSetKey becomes otherwise - * unreachable, the map entry is collected. + * <p>The cache weakly references its values: when the ArtifactNestedSetKey becomes otherwise + * unreachable, the entry is collected. */ - private final ConcurrentMap<NestedSet.Node, ArtifactNestedSetKey> nestedSetToSkyKey = - new MapMaker().weakValues().makeMap(); + private final Cache<NestedSet.Node, ArtifactNestedSetKey> nestedSetToSkyKey = + Caffeine.newBuilder().weakValues().build(); private final Supplier<ArtifactNestedSetValue> valueSupplier; @@ -174,8 +175,7 @@ } for (NestedSet<Artifact> nonLeaf : set.getNonLeaves()) { keys.add( - nestedSetToSkyKey.computeIfAbsent( - nonLeaf.toNode(), (node) -> new ArtifactNestedSetKey(nonLeaf, node))); + nestedSetToSkyKey.get(nonLeaf.toNode(), node -> new ArtifactNestedSetKey(nonLeaf, node))); } return keys; }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD index 076125a..33006ba 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD +++ b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
@@ -830,6 +830,7 @@ "//src/main/java/com/google/devtools/build/lib/util", "//src/main/java/com/google/devtools/build/skyframe", "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", + "//third_party:caffeine", "//third_party:guava", ], )