Skip to content

Commit cd2ea03

Browse files
committed
DATACMNS-332 - Further performance improvements.
Reverted from ConcurrentHashMap to plain HashMap where concurrency wasn't an issue and profiling showed performance hotspots. Introduced caches for ParameterizedTypeInformation.getComponentType() and the resolved raw type in TypeDiscoverer.
1 parent 905565c commit cd2ea03

File tree

5 files changed

+29
-13
lines changed

5 files changed

+29
-13
lines changed

src/main/java/org/springframework/data/mapping/PreferredConstructor.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
import java.lang.annotation.Annotation;
2121
import java.lang.reflect.Constructor;
2222
import java.util.Arrays;
23+
import java.util.HashMap;
2324
import java.util.List;
2425
import java.util.Map;
25-
import java.util.concurrent.ConcurrentHashMap;
2626

2727
import org.springframework.beans.factory.annotation.Value;
2828
import org.springframework.data.annotation.PersistenceConstructor;
@@ -41,13 +41,13 @@ public class PreferredConstructor<T, P extends PersistentProperty<P>> {
4141

4242
private final Constructor<T> constructor;
4343
private final List<Parameter<Object, P>> parameters;
44-
private final Map<PersistentProperty<?>, Boolean> isPropertyParameterCache = new ConcurrentHashMap<PersistentProperty<?>, Boolean>();
44+
private final Map<PersistentProperty<?>, Boolean> isPropertyParameterCache = new HashMap<PersistentProperty<?>, Boolean>();
4545

4646
/**
4747
* Creates a new {@link PreferredConstructor} from the given {@link Constructor} and {@link Parameter}s.
4848
*
49-
* @param constructor
50-
* @param parameters
49+
* @param constructor must not be {@literal null}.
50+
* @param parameters must not be {@literal null}.
5151
*/
5252
public PreferredConstructor(Constructor<T> constructor, Parameter<Object, P>... parameters) {
5353

@@ -167,6 +167,7 @@ public static class Parameter<T, P extends PersistentProperty<P>> {
167167
private final PersistentEntity<T, P> entity;
168168

169169
private Boolean enclosingClassCache;
170+
private Boolean hasSpelExpression;
170171

171172
/**
172173
* Creates a new {@link Parameter} with the given name, {@link TypeInformation} as well as an array of
@@ -240,7 +241,12 @@ public String getSpelExpression() {
240241
* @return
241242
*/
242243
public boolean hasSpelExpression() {
243-
return StringUtils.hasText(getSpelExpression());
244+
245+
if (this.hasSpelExpression == null) {
246+
this.hasSpelExpression = StringUtils.hasText(getSpelExpression());
247+
}
248+
249+
return this.hasSpelExpression;
244250
}
245251

246252
/**

src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929
import java.util.List;
3030
import java.util.Map;
3131
import java.util.Set;
32-
import java.util.concurrent.ConcurrentHashMap;
33-
import java.util.concurrent.ConcurrentMap;
3432
import java.util.concurrent.locks.Lock;
3533
import java.util.concurrent.locks.ReentrantReadWriteLock;
3634

@@ -65,7 +63,7 @@
6563
public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?, P>, P extends PersistentProperty<P>>
6664
implements MappingContext<E, P>, ApplicationEventPublisherAware, InitializingBean {
6765

68-
private final ConcurrentMap<TypeInformation<?>, E> persistentEntities = new ConcurrentHashMap<TypeInformation<?>, E>();
66+
private final Map<TypeInformation<?>, E> persistentEntities = new HashMap<TypeInformation<?>, E>();
6967

7068
private ApplicationEventPublisher applicationEventPublisher;
7169

src/main/java/org/springframework/data/util/ParameterizedTypeInformation.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
class ParameterizedTypeInformation<T> extends ParentTypeAwareTypeInformation<T> {
3636

3737
private final ParameterizedType type;
38+
private TypeInformation<?> componentType;
3839

3940
/**
4041
* Creates a new {@link ParameterizedTypeInformation} for the given {@link Type} and parent {@link TypeDiscoverer}.
@@ -136,7 +137,12 @@ public boolean isAssignableFrom(TypeInformation<?> target) {
136137
*/
137138
@Override
138139
public TypeInformation<?> getComponentType() {
139-
return createInfo(type.getActualTypeArguments()[0]);
140+
141+
if (componentType == null) {
142+
this.componentType = createInfo(type.getActualTypeArguments()[0]);
143+
}
144+
145+
return this.componentType;
140146
}
141147

142148
/*

src/main/java/org/springframework/data/util/TypeDiscoverer.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ class TypeDiscoverer<S> implements TypeInformation<S> {
5151
private final Map<TypeVariable, Type> typeVariableMap;
5252
private final Map<String, TypeInformation<?>> fieldTypes = new ConcurrentHashMap<String, TypeInformation<?>>();
5353

54+
private Class<S> resolvedType;
55+
5456
/**
5557
* Creates a ne {@link TypeDiscoverer} for the given type, type variable map and parent.
5658
*
@@ -261,7 +263,12 @@ private static Type getGenericType(PropertyDescriptor descriptor) {
261263
* @see org.springframework.data.util.TypeInformation#getType()
262264
*/
263265
public Class<S> getType() {
264-
return resolveType(type);
266+
267+
if (resolvedType == null) {
268+
this.resolvedType = resolveType(type);
269+
}
270+
271+
return this.resolvedType;
265272
}
266273

267274
/*

src/test/java/org/springframework/data/mapping/model/AbstractAnnotationBasedPropertyUnitTests.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import java.lang.annotation.RetentionPolicy;
2525
import java.lang.annotation.Target;
2626
import java.util.Map;
27-
import java.util.concurrent.ConcurrentMap;
2827

2928
import org.junit.Before;
3029
import org.junit.Test;
@@ -108,8 +107,8 @@ public void discoversAmbiguousMappingUsingDirectAnnotationsOnAccessors() {
108107
context.getPersistentEntity(InvalidSample.class);
109108
fail("Expected MappingException!");
110109
} catch (MappingException o_O) {
111-
ConcurrentMap<TypeInformation<?>, ?> entities = (ConcurrentMap<TypeInformation<?>, ?>) ReflectionTestUtils
112-
.getField(context, "persistentEntities");
110+
Map<TypeInformation<?>, ?> entities = (Map<TypeInformation<?>, ?>) ReflectionTestUtils.getField(context,
111+
"persistentEntities");
113112
assertThat(entities.containsKey(ClassTypeInformation.from(InvalidSample.class)), is(false));
114113
}
115114
}

0 commit comments

Comments
 (0)