Polishing.
Use double checked locking to be as close to the previous implementation but still benefit from the fast read operation. Original Pull Request: #3186
This commit is contained in:
@@ -497,7 +497,7 @@ public class CustomConversions {
|
||||
*/
|
||||
static class ConversionTargetsCache {
|
||||
|
||||
private Map<Class<?>, TargetTypes> customReadTargetTypes = new HashMap<>();
|
||||
private volatile Map<Class<?>, TargetTypes> customReadTargetTypes = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Get or compute a target type given its {@code sourceType}. Returns a cached {@link Optional} if the value
|
||||
@@ -531,10 +531,19 @@ public class CustomConversions {
|
||||
|
||||
if (targetTypes == null) {
|
||||
|
||||
Map<Class<?>, TargetTypes> customReadTargetTypes = new HashMap<>(this.customReadTargetTypes);
|
||||
targetTypes = new TargetTypes(sourceType);
|
||||
customReadTargetTypes.put(sourceType, targetTypes);
|
||||
this.customReadTargetTypes = customReadTargetTypes;
|
||||
synchronized (this) {
|
||||
|
||||
TargetTypes customReadTarget = customReadTargetTypes.get(sourceType);
|
||||
if (customReadTarget != null) {
|
||||
targetTypes = customReadTarget;
|
||||
} else {
|
||||
|
||||
Map<Class<?>, TargetTypes> customReadTargetTypes = new HashMap<>(this.customReadTargetTypes);
|
||||
targetTypes = new TargetTypes(sourceType);
|
||||
customReadTargetTypes.put(sourceType, targetTypes);
|
||||
this.customReadTargetTypes = customReadTargetTypes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return targetTypes.computeIfAbsent(targetType, mappingFunction);
|
||||
@@ -554,7 +563,7 @@ public class CustomConversions {
|
||||
static class TargetTypes {
|
||||
|
||||
private final Class<?> sourceType;
|
||||
private Map<Class<?>, Class<?>> conversionTargets = new HashMap<>();
|
||||
private volatile Map<Class<?>, Class<?>> conversionTargets = new HashMap<>();
|
||||
|
||||
TargetTypes(Class<?> sourceType) {
|
||||
this.sourceType = sourceType;
|
||||
@@ -576,11 +585,19 @@ public class CustomConversions {
|
||||
|
||||
if (optionalTarget == null) {
|
||||
|
||||
optionalTarget = mappingFunction.apply(new ConvertiblePair(sourceType, targetType));
|
||||
synchronized (this) {
|
||||
|
||||
Map<Class<?>, Class<?>> conversionTargets = new HashMap<>(this.conversionTargets);
|
||||
conversionTargets.put(targetType, optionalTarget == null ? Void.class : optionalTarget);
|
||||
this.conversionTargets = conversionTargets;
|
||||
Class<?> conversionTarget = conversionTargets.get(targetType);
|
||||
if (conversionTarget != null) {
|
||||
optionalTarget = conversionTarget;
|
||||
} else {
|
||||
|
||||
optionalTarget = mappingFunction.apply(new ConvertiblePair(sourceType, targetType));
|
||||
Map<Class<?>, Class<?>> conversionTargets = new HashMap<>(this.conversionTargets);
|
||||
conversionTargets.put(targetType, optionalTarget == null ? Void.class : optionalTarget);
|
||||
this.conversionTargets = conversionTargets;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Void.class.equals(optionalTarget) ? null : optionalTarget;
|
||||
|
||||
@@ -53,7 +53,7 @@ public class SimplePropertyValueConversions implements PropertyValueConversions,
|
||||
|
||||
private @Nullable ValueConverterRegistry<?> valueConverterRegistry;
|
||||
|
||||
private Map<PersistentProperty<?>, PropertyValueConverter<?, ?, ?>> converterCache = new HashMap<>();
|
||||
private volatile Map<PersistentProperty<?>, PropertyValueConverter<?, ?, ?>> converterCache = new HashMap<>();
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
enum NoOpConverter implements PropertyValueConverter {
|
||||
@@ -171,17 +171,21 @@ public class SimplePropertyValueConversions implements PropertyValueConversions,
|
||||
|
||||
if (converter == null) {
|
||||
|
||||
converter = requireConverterFactory().getConverter(property);
|
||||
synchronized (this) {
|
||||
|
||||
Map<PersistentProperty<?>, PropertyValueConverter<?, ?, ?>> converterCache = new HashMap<>(this.converterCache);
|
||||
PropertyValueConverter<?, ?, ?> fromCache = converterCache.get(property);
|
||||
if (fromCache != null) {
|
||||
converter = fromCache;
|
||||
} else {
|
||||
|
||||
if (converter == null) {
|
||||
converterCache.put(property, NoOpConverter.INSTANCE);
|
||||
} else {
|
||||
converterCache.put(property, converter);
|
||||
converter = requireConverterFactory().getConverter(property);
|
||||
|
||||
Map<PersistentProperty<?>, PropertyValueConverter<?, ?, ?>> converterCache = new HashMap<>(
|
||||
this.converterCache);
|
||||
converterCache.put(property, converter != null ? converter : NoOpConverter.INSTANCE);
|
||||
this.converterCache = converterCache;
|
||||
}
|
||||
}
|
||||
|
||||
this.converterCache = converterCache;
|
||||
}
|
||||
|
||||
if (converter == NoOpConverter.INSTANCE) {
|
||||
|
||||
@@ -35,7 +35,7 @@ class InstanceCreatorMetadataSupport<T, P extends PersistentProperty<P>> impleme
|
||||
|
||||
private final Executable executable;
|
||||
private final List<Parameter<Object, P>> parameters;
|
||||
private Map<PersistentProperty<?>, Boolean> isPropertyParameterCache = new HashMap<>();
|
||||
private volatile Map<PersistentProperty<?>, Boolean> isPropertyParameterCache = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Creates a new {@link InstanceCreatorMetadataSupport} from the given {@link Executable} and {@link Parameter}s.
|
||||
@@ -90,17 +90,25 @@ class InstanceCreatorMetadataSupport<T, P extends PersistentProperty<P>> impleme
|
||||
|
||||
Boolean cached = isPropertyParameterCache.get(property);
|
||||
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
if (cached == null) {
|
||||
|
||||
synchronized (this) {
|
||||
|
||||
Boolean fromCache = isPropertyParameterCache.get(property);
|
||||
if (fromCache != null) {
|
||||
cached = fromCache;
|
||||
} else {
|
||||
|
||||
cached = doGetIsCreatorParameter(property);
|
||||
|
||||
Map<PersistentProperty<?>, Boolean> isPropertyParameterCache = new HashMap<>(this.isPropertyParameterCache);
|
||||
isPropertyParameterCache.put(property, cached);
|
||||
this.isPropertyParameterCache = isPropertyParameterCache;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean result = doGetIsCreatorParameter(property);
|
||||
|
||||
Map<PersistentProperty<?>, Boolean> isPropertyParameterCache = new HashMap<>(this.isPropertyParameterCache);
|
||||
isPropertyParameterCache.put(property, result);
|
||||
this.isPropertyParameterCache = isPropertyParameterCache;
|
||||
|
||||
return result;
|
||||
return cached;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user