浏览代码

cache forName lookups

tags/2.0.1
Jonathan Cobb 4 年前
父节点
当前提交
c9c5f37387
共有 2 个文件被更改,包括 45 次插入22 次删除
  1. +18
    -4
      src/main/java/org/cobbzilla/util/collection/ExpirationMap.java
  2. +27
    -18
      src/main/java/org/cobbzilla/util/reflect/ReflectionUtil.java

+ 18
- 4
src/main/java/org/cobbzilla/util/collection/ExpirationMap.java 查看文件

@@ -10,11 +10,11 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.concurrent.TimeUnit.HOURS;
import static org.cobbzilla.util.daemon.ZillaRuntime.notSupported;
import static org.cobbzilla.util.daemon.ZillaRuntime.now;
import static org.cobbzilla.util.time.TimeUtil.isTimestampInFuture;
@@ -25,9 +25,9 @@ public class ExpirationMap<K, V> implements Map<K, V> {

private final Map<K, ExpirationMapEntry<V>> map;

@Getter @Setter private long expiration = TimeUnit.HOURS.toMillis(1);
@Getter @Setter private long maxExpiration = TimeUnit.HOURS.toMillis(2);
@Getter @Setter private long cleanInterval = TimeUnit.HOURS.toMillis(4);
@Getter @Setter private long expiration = HOURS.toMillis(1);
@Getter @Setter private long maxExpiration = HOURS.toMillis(2);
@Getter @Setter private long cleanInterval = HOURS.toMillis(4);

public ExpirationMap<K, V> setExpirations(long val) {
final var isNewExpirationShorter = val < this.expiration;
@@ -46,18 +46,32 @@ public class ExpirationMap<K, V> implements Map<K, V> {

public ExpirationMap() { this.map = new ConcurrentHashMap<>(); }

public ExpirationMap(int initialCapacity) { this.map = new ConcurrentHashMap<>(initialCapacity); }

public ExpirationMap(long val) { this(); setExpirations(val); }

public ExpirationMap(int initialCapacity, long val) { this(initialCapacity); setExpirations(val); }

public ExpirationMap(long val, ExpirationEvictionPolicy evictionPolicy) {
this(val);
this.evictionPolicy = evictionPolicy;
}

public ExpirationMap(int initialCapacity, long val, ExpirationEvictionPolicy evictionPolicy) {
this(initialCapacity, val);
this.evictionPolicy = evictionPolicy;
}

public ExpirationMap(ExpirationEvictionPolicy evictionPolicy) {
this();
this.evictionPolicy = evictionPolicy;
}

public ExpirationMap(int initialCapacity, ExpirationEvictionPolicy evictionPolicy) {
this(initialCapacity);
this.evictionPolicy = evictionPolicy;
}

@Accessors(chain=true)
private class ExpirationMapEntry<VAL> {
public final VAL value;


+ 27
- 18
src/main/java/org/cobbzilla/util/reflect/ReflectionUtil.java 查看文件

@@ -26,6 +26,7 @@ import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.reflect.Modifier.isFinal;
import static java.lang.reflect.Modifier.isStatic;
import static java.util.concurrent.TimeUnit.MINUTES;
import static org.apache.commons.lang3.reflect.FieldUtils.getAllFields;
import static org.cobbzilla.util.collection.ArrayUtil.arrayToString;
import static org.cobbzilla.util.daemon.ZillaRuntime.*;
@@ -110,6 +111,8 @@ public class ReflectionUtil {
return null;
}

private static final Map<String, Class> forNameCache = new ExpirationMap<>(100, MINUTES.toMillis(20), ExpirationEvictionPolicy.atime);

/**
* Do a Class.forName and only throw unchecked exceptions.
* @param clazz full class name. May end in [] to indicate array class
@@ -117,26 +120,32 @@ public class ReflectionUtil {
* @return A Class&lt;clazz&gt; object
*/
public static <T> Class<? extends T> forName(String clazz) {
if (empty(clazz)) return (Class<? extends T>) Object.class;
if (clazz.endsWith("[]")) return arrayClass(forName(clazz.substring(0, clazz.length()-2)));
try {
return (Class<? extends T>) Class.forName(clazz);
} catch (ClassNotFoundException e) {
switch (clazz) {
case "boolean": return (Class<? extends T>) boolean.class;
case "byte": return (Class<? extends T>) byte.class;
case "short": return (Class<? extends T>) short.class;
case "char": return (Class<? extends T>) char.class;
case "int": return (Class<? extends T>) int.class;
case "long": return (Class<? extends T>) long.class;
case "float": return (Class<? extends T>) float.class;
case "double": return (Class<? extends T>) double.class;
}
return die("Class.forName("+clazz+") error: "+shortError(e));
Class<? extends T> cached = forNameCache.get(clazz);
if (cached == null) {
if (empty(clazz)) return (Class<? extends T>) Object.class;
if (clazz.endsWith("[]")) return arrayClass(forName(clazz.substring(0, clazz.length()-2)));
try {
cached = (Class<? extends T>) Class.forName(clazz);
forNameCache.put(clazz, cached);

} catch (ClassNotFoundException e) {
switch (clazz) {
case "boolean": return (Class<? extends T>) boolean.class;
case "byte": return (Class<? extends T>) byte.class;
case "short": return (Class<? extends T>) short.class;
case "char": return (Class<? extends T>) char.class;
case "int": return (Class<? extends T>) int.class;
case "long": return (Class<? extends T>) long.class;
case "float": return (Class<? extends T>) float.class;
case "double": return (Class<? extends T>) double.class;
}
return die("Class.forName("+clazz+") error: "+shortError(e));

} catch (Exception e) {
return die("Class.forName("+clazz+") error: "+shortError(e));
} catch (Exception e) {
return die("Class.forName("+clazz+") error: "+shortError(e));
}
}
return cached;
}

public static Collection<Class> forNames(String[] classNames) {


正在加载...
取消
保存