Skip to content

Commit

Permalink
fix performance problems with package annotations. Close #190
Browse files Browse the repository at this point in the history
  • Loading branch information
turbanoff committed Jun 19, 2018
1 parent 8131be2 commit 7a7ee29
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
Expand Up @@ -10,7 +10,9 @@

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
Expand All @@ -21,6 +23,7 @@
* @param <T> A class.
*/
public class ClassAccessor<T> {
private static final Map<Map.Entry<String, Annotation>, Boolean> PACKAGE_ANNOTATION_CACHE = Util.newLruCache(512);
private final Class<T> type;
private final PrefabValues prefabValues;
private final Annotation[] supportedAnnotations;
Expand Down Expand Up @@ -107,10 +110,19 @@ public boolean packageHasAnnotation(Annotation annotation) {
return false;
}

String className = pkg.getName() + ".package-info";
String packageName = pkg.getName();
Map.Entry<String, Annotation> entry = new SimpleImmutableEntry<>(packageName, annotation);
Boolean hasAnnotation = PACKAGE_ANNOTATION_CACHE.get(entry);
if (hasAnnotation != null) {
return hasAnnotation;
}

String className = packageName + ".package-info";
Class<?> packageType = Class.forName(className);
AnnotationAccessor accessor = new AnnotationAccessor(supportedAnnotations, packageType, ignoredAnnotations, ignoreAnnotationFailure);
return accessor.typeHas(annotation);
hasAnnotation = accessor.typeHas(annotation);
PACKAGE_ANNOTATION_CACHE.put(entry, hasAnnotation);
return hasAnnotation;
}
catch (ClassNotFoundException e) {
return false;
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/nl/jqno/equalsverifier/internal/reflection/Util.java
@@ -1,5 +1,9 @@
package nl.jqno.equalsverifier.internal.reflection;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

public final class Util {
private Util() {
// Do not instantiate
Expand Down Expand Up @@ -40,4 +44,20 @@ public static Class<?>[] classes(Class<?>... classes) {
public static Object[] objects(Object... objects) {
return objects;
}

/**
* Helper method to create simple LRU cache implementation
*
* @param maxSize maximum size of map
* @return simple thread-safe map with maximum-size eviction by LRU algorithm
*/
public static <K, V> Map<K, V> newLruCache(final int maxSize) {
LinkedHashMap<K, V> map = new LinkedHashMap<K, V>(16, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > maxSize;
}
};
return Collections.synchronizedMap(map);
}
}
Expand Up @@ -49,7 +49,7 @@ public enum SupportedAnnotations implements Annotation {
* {@link NullPointerException}s being thrown if any of the fields in that
* class or package are null.
*
* Note that @DefaultAnnotation is deprectated. Nevertheless, EqualsVerifier
* Note that @DefaultAnnotation is deprecated. Nevertheless, EqualsVerifier
* still supports it.
*/
FINDBUGS1X_DEFAULT_ANNOTATION_NONNULL(false,
Expand Down

0 comments on commit 7a7ee29

Please sign in to comment.