Convert from MapMaker to CacheBuilder. Change mostly from Stewart McCulloch mcculls@gmail.com modulo internal build issues, a few tweaks and dealing with some test flakage in a functional test.
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=52590552
diff --git a/core/src/com/google/inject/internal/Annotations.java b/core/src/com/google/inject/internal/Annotations.java
index 07e9a83..dfc6936 100644
--- a/core/src/com/google/inject/internal/Annotations.java
+++ b/core/src/com/google/inject/internal/Annotations.java
@@ -20,8 +20,10 @@
import com.google.common.base.Joiner;
import com.google.common.base.Joiner.MapJoiner;
import com.google.common.base.Preconditions;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
import com.google.inject.BindingAnnotation;
import com.google.inject.Key;
@@ -69,11 +71,11 @@
return hasMethods;
}
- private static final Map<Class<? extends Annotation>, Annotation> cache =
- new MapMaker().weakKeys().makeComputingMap(
- new Function<Class<? extends Annotation>, Annotation>() {
+ private static final LoadingCache<Class<? extends Annotation>, Annotation> cache =
+ CacheBuilder.newBuilder().weakKeys().build(
+ new CacheLoader<Class<? extends Annotation>, Annotation>() {
@Override
- public Annotation apply(Class<? extends Annotation> input) {
+ public Annotation load(Class<? extends Annotation> input) {
return generateAnnotationImpl(input);
}
});
@@ -85,7 +87,7 @@
public static <T extends Annotation> T generateAnnotation(Class<T> annotationType) {
Preconditions.checkState(
isAllDefaultMethods(annotationType), "%s is not all default methods", annotationType);
- return (T)cache.get(annotationType);
+ return (T)cache.getUnchecked(annotationType);
}
private static <T extends Annotation> T generateAnnotationImpl(final Class<T> annotationType) {
@@ -206,9 +208,9 @@
private final Collection<Class<? extends Annotation>> annotationTypes;
/** Returns true if the given class has one of the desired annotations. */
- private Function<Class<? extends Annotation>, Boolean> hasAnnotations =
- new Function<Class<? extends Annotation>, Boolean>() {
- public Boolean apply(Class<? extends Annotation> annotationType) {
+ private CacheLoader<Class<? extends Annotation>, Boolean> hasAnnotations =
+ new CacheLoader<Class<? extends Annotation>, Boolean>() {
+ public Boolean load(Class<? extends Annotation> annotationType) {
for (Annotation annotation : annotationType.getAnnotations()) {
if (annotationTypes.contains(annotation.annotationType())) {
return true;
@@ -218,8 +220,8 @@
}
};
- final Map<Class<? extends Annotation>, Boolean> cache = new MapMaker().weakKeys()
- .makeComputingMap(hasAnnotations);
+ final LoadingCache<Class<? extends Annotation>, Boolean> cache = CacheBuilder.newBuilder().weakKeys()
+ .build(hasAnnotations);
/**
* Constructs a new checker that looks for annotations of the given types.
@@ -232,7 +234,7 @@
* Returns true if the given type has one of the desired annotations.
*/
boolean hasAnnotations(Class<? extends Annotation> annotated) {
- return cache.get(annotated);
+ return cache.getUnchecked(annotated);
}
}
@@ -305,7 +307,7 @@
*/
public static Annotation canonicalizeIfNamed(Annotation annotation) {
if(annotation instanceof javax.inject.Named) {
- return Names.named(((javax.inject.Named)annotation).value());
+ return Names.named(((javax.inject.Named)annotation).value());
} else {
return annotation;
}
diff --git a/core/src/com/google/inject/internal/BytecodeGen.java b/core/src/com/google/inject/internal/BytecodeGen.java
index d0a14fc..ad7764b 100644
--- a/core/src/com/google/inject/internal/BytecodeGen.java
+++ b/core/src/com/google/inject/internal/BytecodeGen.java
@@ -16,9 +16,9 @@
package com.google.inject.internal;
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.MapMaker;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
@@ -26,7 +26,6 @@
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.Map;
import java.util.logging.Logger;
/**
@@ -83,7 +82,7 @@
@Override protected String getTag() {
return "ByGuice";
}
-
+
@Override
public String getClassName(String prefix, String source, Object key,
net.sf.cglib.core.Predicate names) {
@@ -94,7 +93,7 @@
return super.getClassName(prefix, "FastClass", key, names);
}
};
-
+
static final net.sf.cglib.core.NamingPolicy ENHANCER_NAMING_POLICY
= new net.sf.cglib.core.DefaultNamingPolicy() {
@Override
@@ -125,24 +124,24 @@
* Weak cache of bridge class loaders that make the Guice implementation
* classes visible to various code-generated proxies of client classes.
*/
- private static final Map<ClassLoader, ClassLoader> CLASS_LOADER_CACHE;
+ private static final LoadingCache<ClassLoader, ClassLoader> CLASS_LOADER_CACHE;
static {
- if (CUSTOM_LOADER_ENABLED) {
- CLASS_LOADER_CACHE = new MapMaker().weakKeys().weakValues().makeComputingMap(
- new Function<ClassLoader, ClassLoader>() {
- public ClassLoader apply(final ClassLoader typeClassLoader) {
- logger.fine("Creating a bridge ClassLoader for " + typeClassLoader);
- return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
- public ClassLoader run() {
- return new BridgeClassLoader(typeClassLoader);
- }
- });
- }
- });
- } else {
- CLASS_LOADER_CACHE = ImmutableMap.of();
+ CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder().weakKeys().weakValues();
+ if (!CUSTOM_LOADER_ENABLED) {
+ builder.maximumSize(0);
}
+ CLASS_LOADER_CACHE = builder.build(
+ new CacheLoader<ClassLoader, ClassLoader>() {
+ public ClassLoader load(final ClassLoader typeClassLoader) {
+ logger.fine("Creating a bridge ClassLoader for " + typeClassLoader);
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return new BridgeClassLoader(typeClassLoader);
+ }
+ });
+ }
+ });
}
/**
@@ -166,7 +165,7 @@
if (!CUSTOM_LOADER_ENABLED) {
return delegate;
}
-
+
// java.* types can be seen everywhere
if (type.getName().startsWith("java.")) {
return GUICE_CLASS_LOADER;
@@ -183,7 +182,7 @@
if (Visibility.forType(type) == Visibility.PUBLIC) {
if (delegate != SystemBridgeHolder.SYSTEM_BRIDGE.getParent()) {
// delegate guaranteed to be non-null here
- return CLASS_LOADER_CACHE.get(delegate);
+ return CLASS_LOADER_CACHE.getUnchecked(delegate);
}
// delegate may or may not be null here
return SystemBridgeHolder.SYSTEM_BRIDGE;
diff --git a/core/src/com/google/inject/internal/FailableCache.java b/core/src/com/google/inject/internal/FailableCache.java
index e392e0d..acd8be5 100644
--- a/core/src/com/google/inject/internal/FailableCache.java
+++ b/core/src/com/google/inject/internal/FailableCache.java
@@ -16,10 +16,9 @@
package com.google.inject.internal;
-import com.google.common.base.Function;
-import com.google.common.collect.MapMaker;
-
-import java.util.Map;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
/**
* Lazily creates (and caches) values for keys. If creating the value fails (with errors), an
@@ -29,9 +28,9 @@
*/
public abstract class FailableCache<K, V> {
- private final Map<K, Object> delegate = new MapMaker().makeComputingMap(
- new Function<K, Object>() {
- public Object apply(K key) {
+ private final LoadingCache<K, Object> delegate = CacheBuilder.newBuilder().build(
+ new CacheLoader<K, Object>() {
+ public Object load(K key) {
Errors errors = new Errors();
V result = null;
try {
@@ -46,7 +45,7 @@
protected abstract V create(K key, Errors errors) throws ErrorsException;
public V get(K key, Errors errors) throws ErrorsException {
- Object resultOrError = delegate.get(key);
+ Object resultOrError = delegate.getUnchecked(key);
if (resultOrError instanceof Errors) {
errors.merge((Errors) resultOrError);
throw errors.toException();
@@ -58,6 +57,6 @@
}
boolean remove(K key) {
- return delegate.remove(key) != null;
+ return delegate.asMap().remove(key) != null;
}
}
diff --git a/core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java b/core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java
index 631a05f..1074628 100644
--- a/core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java
+++ b/core/src/com/google/inject/internal/ProvisionListenerCallbackStore.java
@@ -16,11 +16,12 @@
package com.google.inject.internal;
-import com.google.common.base.Function;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
-import com.google.common.collect.MapMaker;
import com.google.inject.Binding;
import com.google.inject.Injector;
import com.google.inject.Key;
@@ -29,7 +30,6 @@
import com.google.inject.spi.ProvisionListenerBinding;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
@@ -47,10 +47,10 @@
private final ImmutableList<ProvisionListenerBinding> listenerBindings;
- private final Map<KeyBinding, ProvisionListenerStackCallback<?>> cache
- = new MapMaker().makeComputingMap(
- new Function<KeyBinding, ProvisionListenerStackCallback<?>>() {
- public ProvisionListenerStackCallback<?> apply(KeyBinding key) {
+ private final LoadingCache<KeyBinding, ProvisionListenerStackCallback<?>> cache
+ = CacheBuilder.newBuilder().build(
+ new CacheLoader<KeyBinding, ProvisionListenerStackCallback<?>>() {
+ public ProvisionListenerStackCallback<?> load(KeyBinding key) {
return create(key.binding);
}
});
@@ -65,7 +65,7 @@
public <T> ProvisionListenerStackCallback<T> get(Binding<T> binding) {
// Never notify any listeners for internal bindings.
if (!INTERNAL_BINDINGS.contains(binding.getKey())) {
- return (ProvisionListenerStackCallback<T>) cache.get(
+ return (ProvisionListenerStackCallback<T>) cache.getUnchecked(
new KeyBinding(binding.getKey(), binding));
}
return ProvisionListenerStackCallback.emptyListener();
@@ -81,7 +81,7 @@
* Returns true if the type was stored in the cache, false otherwise.
*/
boolean remove(Binding<?> type) {
- return cache.remove(type) != null;
+ return cache.asMap().remove(type) != null;
}
/**
diff --git a/core/src/com/google/inject/internal/util/StackTraceElements.java b/core/src/com/google/inject/internal/util/StackTraceElements.java
index 80580b5..db10c28 100644
--- a/core/src/com/google/inject/internal/util/StackTraceElements.java
+++ b/core/src/com/google/inject/internal/util/StackTraceElements.java
@@ -16,7 +16,9 @@
package com.google.inject.internal.util;
-import com.google.common.base.Function;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
import com.google.common.collect.MapMaker;
import java.io.IOException;
@@ -32,22 +34,23 @@
public class StackTraceElements {
/*if[AOP]*/
- static final Map<Class<?>, LineNumbers> lineNumbersCache = new MapMaker().weakKeys().softValues()
- .makeComputingMap(new Function<Class<?>, LineNumbers>() {
- public LineNumbers apply(Class<?> key) {
- try {
- return new LineNumbers(key);
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- });
+ static final LoadingCache<Class<?>, LineNumbers> lineNumbersCache =
+ CacheBuilder.newBuilder().weakKeys().softValues().build(
+ new CacheLoader<Class<?>, LineNumbers>() {
+ public LineNumbers load(Class<?> key) {
+ try {
+ return new LineNumbers(key);
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
/*end[AOP]*/
-
+
private static Map<Object, Object> cache = new MapMaker().makeMap();
private static final String UNKNOWN_SOURCE = "Unknown Source";
-
+
public static Object forMember(Member member) {
if (member == null) {
return SourceProvider.UNKNOWN_SOURCE;
@@ -56,7 +59,7 @@
Class declaringClass = member.getDeclaringClass();
/*if[AOP]*/
- LineNumbers lineNumbers = lineNumbersCache.get(declaringClass);
+ LineNumbers lineNumbers = lineNumbersCache.getUnchecked(declaringClass);
String fileName = lineNumbers.getSource();
Integer lineNumberOrNull = lineNumbers.getLineNumber(member);
int lineNumber = lineNumberOrNull == null ? lineNumbers.getFirstLine() : lineNumberOrNull;
@@ -73,7 +76,7 @@
public static Object forType(Class<?> implementation) {
/*if[AOP]*/
- LineNumbers lineNumbers = lineNumbersCache.get(implementation);
+ LineNumbers lineNumbers = lineNumbersCache.getUnchecked(implementation);
int lineNumber = lineNumbers.getFirstLine();
String fileName = lineNumbers.getSource();
/*end[AOP]*/
diff --git a/core/test/com/googlecode/guice/BytecodeGenTest.java b/core/test/com/googlecode/guice/BytecodeGenTest.java
index a62aacc..de4d560 100644
--- a/core/test/com/googlecode/guice/BytecodeGenTest.java
+++ b/core/test/com/googlecode/guice/BytecodeGenTest.java
@@ -38,6 +38,7 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
+import java.util.concurrent.TimeoutException;
/**
* This test is in a separate package so we can test package-level visibility
@@ -80,14 +81,14 @@
Injector injector = Guice.createInjector(interceptorModule, new PackageVisibilityTestModule());
injector.getInstance(PublicUserOfPackagePrivate.class); // This must pass.
}
-
+
public void testEnhancerNaming() {
Injector injector = Guice.createInjector(interceptorModule, new PackageVisibilityTestModule());
PublicUserOfPackagePrivate pupp = injector.getInstance(PublicUserOfPackagePrivate.class);
assertTrue(pupp.getClass().getName().startsWith(
PublicUserOfPackagePrivate.class.getName() + "$$EnhancerByGuice$$"));
}
-
+
// TODO(sameb): Figure out how to test FastClass naming tests.
/**
@@ -228,7 +229,7 @@
assertNotSame(testProxy.getClass().getClassLoader(), systemClassLoader);
}
}
-
+
public void testProxyClassUnloading() {
Object testObject = Guice.createInjector(interceptorModule, testModule)
.getInstance(proxyTestClass);
@@ -247,24 +248,21 @@
* this should be enough to queue the weak reference
* unless something is holding onto it accidentally.
*/
+ final int MAX_COUNT = 100;
String[] buf;
System.gc();
- buf = new String[8 * 1024 * 1024];
- buf = null;
- System.gc();
- buf = new String[8 * 1024 * 1024];
- buf = null;
- System.gc();
- buf = new String[8 * 1024 * 1024];
- buf = null;
- System.gc();
- buf = new String[8 * 1024 * 1024];
- buf = null;
- System.gc();
+ //TODO(cgruber): Use com.google.common.testing.GcFinalization and a countdown latch to un-flake.
+ for (int count = 0 ; clazzRef.get() != null ; count++) {
+ buf = new String[8 * 1024 * 1024];
+ buf = null;
+ System.gc();
+ assertTrue("Timeout waiting for class to be unloaded. This may be a flaky result.",
+ count <= MAX_COUNT);
+ }
// This test could be somewhat flaky when the GC isn't working.
// If it fails, run the test again to make sure it's failing reliably.
- assertNull(clazzRef.get());
+ assertNull("Proxy class was not unloaded.", clazzRef.get());
}
public void testProxyingPackagePrivateMethods() {