diff --git a/.gitignore b/.gitignore
index b6cd1d6..ca92ae7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@ target/
.classpath
.project
.settings
+.idea
+*.iml
diff --git a/pom.xml b/pom.xml
index fcfba55..3f161e3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,4 +1,3 @@
-
4.0.0
@@ -127,4 +126,4 @@
git@github.com:HubSpot/jackson-datatype-protobuf.git
HEAD
-
+
\ No newline at end of file
diff --git a/src/main/java/com/hubspot/jackson/datatype/protobuf/ExtensionRegistryWrapper.java b/src/main/java/com/hubspot/jackson/datatype/protobuf/ExtensionRegistryWrapper.java
index 154b634..a1014de 100644
--- a/src/main/java/com/hubspot/jackson/datatype/protobuf/ExtensionRegistryWrapper.java
+++ b/src/main/java/com/hubspot/jackson/datatype/protobuf/ExtensionRegistryWrapper.java
@@ -1,27 +1,23 @@
package com.hubspot.jackson.datatype.protobuf;
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.ExtensionRegistry;
+import com.google.protobuf.ExtensionRegistry.ExtensionInfo;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-
-import com.google.protobuf.Descriptors.Descriptor;
-import com.google.protobuf.ExtensionRegistry;
-import com.google.protobuf.ExtensionRegistry.ExtensionInfo;
+import java.util.function.Function;
public class ExtensionRegistryWrapper {
private final Function> extensionFunction;
private ExtensionRegistryWrapper() {
- this.extensionFunction = new Function>() {
-
- @Override
- public Set apply(Descriptor descriptor) {
- return Collections.emptySet();
- }
- };
+ this.extensionFunction = descriptor -> Collections.emptySet();
}
private ExtensionRegistryWrapper(final ExtensionRegistry extensionRegistry) {
@@ -30,20 +26,13 @@ private ExtensionRegistryWrapper(final ExtensionRegistry extensionRegistry) {
@Override
public Set apply(Descriptor descriptor) {
- Set cached = extensionCache.get(descriptor);
- if (cached != null) {
- return cached;
- }
-
- Set extensions =
- extensionRegistry.getAllImmutableExtensionsByExtendedType(descriptor.getFullName());
- extensionCache.put(descriptor, extensions);
- return extensions;
+ return extensionCache.computeIfAbsent(descriptor, key -> extensionRegistry.getAllImmutableExtensionsByExtendedType(descriptor.getFullName()));
}
};
}
public static ExtensionRegistryWrapper wrap(ExtensionRegistry extensionRegistry) {
+ Objects.requireNonNull(extensionRegistry, "extensionRegistry should not be null!");
return new ExtensionRegistryWrapper(extensionRegistry);
}
@@ -62,8 +51,4 @@ public List findExtensionsByDescriptor(Descriptor descriptor) {
public Set getExtensionsByDescriptor(Descriptor descriptor) {
return extensionFunction.apply(descriptor);
}
-
- private interface Function {
- V apply(T t);
- }
}
diff --git a/src/main/java/com/hubspot/jackson/datatype/protobuf/PropertyNamingStrategyWrapper.java b/src/main/java/com/hubspot/jackson/datatype/protobuf/PropertyNamingStrategyWrapper.java
index 2292f33..acedc8d 100644
--- a/src/main/java/com/hubspot/jackson/datatype/protobuf/PropertyNamingStrategyWrapper.java
+++ b/src/main/java/com/hubspot/jackson/datatype/protobuf/PropertyNamingStrategyWrapper.java
@@ -1,12 +1,14 @@
package com.hubspot.jackson.datatype.protobuf;
-import java.lang.reflect.Method;
-
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.PropertyNamingStrategy.PropertyNamingStrategyBase;
import com.google.common.base.CaseFormat;
-@SuppressWarnings("serial")
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
+@SuppressWarnings("deprecation")
public class PropertyNamingStrategyWrapper extends PropertyNamingStrategyBase {
private static final PropertyNamingStrategyBase SNAKE_TO_CAMEL = new SnakeToCamelNamingStrategy();
private static final PropertyNamingStrategyBase NO_OP = new NoOpNamingStrategy();
@@ -49,7 +51,7 @@ public String translate(String fieldName) {
private static class NamingBaseAdapter extends PropertyNamingStrategyBase {
private static final Class> NAMING_BASE = tryToLoadNamingBase();
- private static final Method TRANSLATE_METHOD = tryToLoadTranslateMethod(NAMING_BASE);
+ private static final MethodHandle TRANSLATE_METHOD = tryToLoadTranslateMethod(NAMING_BASE);
private final PropertyNamingStrategy delegate;
@@ -65,7 +67,7 @@ public static boolean extendsNamingBase(PropertyNamingStrategy namingStrategy) {
public String translate(String fieldName) {
try {
return (String) TRANSLATE_METHOD.invoke(delegate, fieldName);
- } catch (ReflectiveOperationException e) {
+ } catch (Throwable e) {
throw new RuntimeException("Unable to invoke translate method", e);
}
}
@@ -78,13 +80,13 @@ private static Class> tryToLoadNamingBase() {
}
}
- private static Method tryToLoadTranslateMethod(Class> namingBase) {
+ private static MethodHandle tryToLoadTranslateMethod(Class> namingBase) {
if (namingBase == null) {
return null;
} else {
try {
- return namingBase.getMethod("translate", String.class);
- } catch (NoSuchMethodException e) {
+ return MethodHandles.publicLookup().findVirtual(namingBase, "translate", MethodType.methodType(String.class, String.class));
+ } catch (NoSuchMethodException | IllegalAccessException e) {
throw new RuntimeException("Unable to find translate method on class: " + namingBase);
}
}
diff --git a/src/main/java/com/hubspot/jackson/datatype/protobuf/internal/PropertyNamingCache.java b/src/main/java/com/hubspot/jackson/datatype/protobuf/internal/PropertyNamingCache.java
index 1b975a9..5fbc537 100644
--- a/src/main/java/com/hubspot/jackson/datatype/protobuf/internal/PropertyNamingCache.java
+++ b/src/main/java/com/hubspot/jackson/datatype/protobuf/internal/PropertyNamingCache.java
@@ -1,30 +1,38 @@
package com.hubspot.jackson.datatype.protobuf.internal;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.function.Function;
-
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.PropertyNamingStrategy.PropertyNamingStrategyBase;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.MapMaker;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.hubspot.jackson.datatype.protobuf.PropertyNamingStrategyWrapper;
import com.hubspot.jackson.datatype.protobuf.ProtobufJacksonConfig;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Function;
+
public class PropertyNamingCache {
+
+ private static final int DEFAULT_CONCURRENCY_LEVEL = Math.min(Runtime.getRuntime().availableProcessors(), 16);
private final Descriptor descriptor;
private final ProtobufJacksonConfig config;
private final Map> serializationCache;
private final Map> deserializationCache;
+ private static ConcurrentMap buildWeakMap() {
+ return new MapMaker().concurrencyLevel(DEFAULT_CONCURRENCY_LEVEL).weakKeys().makeMap();
+ }
+
private PropertyNamingCache(Descriptor descriptor, ProtobufJacksonConfig config) {
this.descriptor = descriptor;
this.config = config;
- this.serializationCache = Collections.synchronizedMap(new WeakHashMap<>());
- this.deserializationCache = Collections.synchronizedMap(new WeakHashMap<>());
+ this.serializationCache = buildWeakMap();
+ this.deserializationCache = buildWeakMap();
}
public static PropertyNamingCache forDescriptor(Descriptor descriptor, ProtobufJacksonConfig config) {
@@ -32,31 +40,14 @@ public static PropertyNamingCache forDescriptor(Descriptor descriptor, ProtobufJ
}
public Function forSerialization(PropertyNamingStrategy propertyNamingStrategy) {
- Function cached = serializationCache.get(propertyNamingStrategy);
- if (cached != null) {
- return cached;
- } else {
- Function function = buildSerializationFunction(descriptor, propertyNamingStrategy);
- serializationCache.put(propertyNamingStrategy, function);
-
- return function;
- }
+ return serializationCache.computeIfAbsent(propertyNamingStrategy, this::buildSerializationFunction);
}
public Function forDeserialization(PropertyNamingStrategy propertyNamingStrategy) {
- Function cached = deserializationCache.get(propertyNamingStrategy);
- if (cached != null) {
- return cached;
- } else {
- Function function = buildDeserializationFunction(descriptor, propertyNamingStrategy);
- deserializationCache.put(propertyNamingStrategy, function);
-
- return function;
- }
+ return deserializationCache.computeIfAbsent(propertyNamingStrategy,this::buildDeserializationFunction);
}
private Function buildSerializationFunction(
- Descriptor descriptor,
PropertyNamingStrategy originalNamingStrategy
) {
PropertyNamingStrategyBase namingStrategy =
@@ -75,7 +66,6 @@ private Function buildSerializationFunction(
}
private Function buildDeserializationFunction(
- Descriptor descriptor,
PropertyNamingStrategy originalNamingStrategy
) {
PropertyNamingStrategyBase namingStrategy =