Skip to content

Commit 66b91b4

Browse files
committed
Introduce caching for commonly used model computations.
We now cache the outcome for column types, AnnotatedType lookuop by annotation and bypass the conversion service by considering primitive type wrappers in the assignability check. Closes #1218
1 parent ac2bf3e commit 66b91b4

File tree

4 files changed

+47
-3
lines changed

4 files changed

+47
-3
lines changed

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/DefaultColumnTypeResolver.java

+26-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Map;
2323
import java.util.Optional;
2424
import java.util.Set;
25+
import java.util.concurrent.ConcurrentHashMap;
2526
import java.util.function.Supplier;
2627
import java.util.stream.StreamSupport;
2728

@@ -76,6 +77,8 @@ class DefaultColumnTypeResolver implements ColumnTypeResolver {
7677
private final UserTypeResolver userTypeResolver;
7778
private final Supplier<CodecRegistry> codecRegistry;
7879
private final Supplier<CustomConversions> customConversions;
80+
private final Map<CassandraPersistentProperty, CassandraColumnType> columnTypeCache = new ConcurrentHashMap<>();
81+
private final Map<TypeInformation<?>, CassandraColumnType> typeInformationColumnTypeCache = new ConcurrentHashMap<>();
7982

8083
/**
8184
* Creates a new {@link DefaultColumnTypeResolver}.
@@ -100,6 +103,18 @@ public CassandraColumnType resolve(CassandraPersistentProperty property) {
100103

101104
Assert.notNull(property, "Property must not be null");
102105

106+
CassandraColumnType cassandraColumnType = columnTypeCache.get(property);
107+
if (cassandraColumnType == null) {
108+
// avoid recursive update
109+
cassandraColumnType = doResolve(property);
110+
columnTypeCache.put(property, cassandraColumnType);
111+
}
112+
113+
return cassandraColumnType;
114+
}
115+
116+
private CassandraColumnType doResolve(CassandraPersistentProperty property) {
117+
103118
if (property.isAnnotationPresent(CassandraType.class)) {
104119

105120
CassandraType annotation = property.getRequiredAnnotation(CassandraType.class);
@@ -169,7 +184,17 @@ private boolean isFrozen(AnnotatedType type) {
169184
*/
170185
@Override
171186
public CassandraColumnType resolve(TypeInformation<?> typeInformation) {
172-
return resolve(typeInformation, FrozenIndicator.NOT_FROZEN);
187+
188+
Assert.notNull(typeInformation, "TypeInformation must not be null");
189+
190+
CassandraColumnType cassandraColumnType = typeInformationColumnTypeCache.get(typeInformation);
191+
if (cassandraColumnType == null) {
192+
// avoid recursive update
193+
cassandraColumnType = resolve(typeInformation, FrozenIndicator.NOT_FROZEN);
194+
typeInformationColumnTypeCache.put(typeInformation, cassandraColumnType);
195+
}
196+
197+
return cassandraColumnType;
173198
}
174199

175200
private CassandraColumnType resolve(TypeInformation<?> typeInformation, FrozenIndicator frozen) {

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/convert/MappingCassandraConverter.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -926,7 +926,8 @@ protected Object getPotentiallyConvertedSimpleRead(Object value, TypeInformation
926926
@SuppressWarnings({ "rawtypes", "unchecked" })
927927
private Object getPotentiallyConvertedSimpleRead(Object value, @Nullable Class<?> target) {
928928

929-
if (value == null || target == null || target.isAssignableFrom(value.getClass())) {
929+
if (value == null || target == null
930+
|| ClassUtils.resolvePrimitiveIfNecessary(target).isAssignableFrom(value.getClass())) {
930931
return value;
931932
}
932933

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/BasicCassandraPersistentProperty.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ public CqlIdentifier getColumnName() {
113113
this.columnName = determineColumnName();
114114
}
115115

116-
Assert.state(this.columnName != null, () -> String.format("Cannot determine column name for %s", this));
116+
if (columnName == null) {
117+
throw new IllegalStateException(String.format("Cannot determine column name for %s", this));
118+
}
117119

118120
return this.columnName;
119121
}

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/mapping/CachingCassandraPersistentProperty.java

+16
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
*/
1616
package org.springframework.data.cassandra.core.mapping;
1717

18+
import java.lang.annotation.Annotation;
19+
import java.lang.reflect.AnnotatedType;
20+
import java.util.Map;
21+
import java.util.Optional;
22+
import java.util.concurrent.ConcurrentHashMap;
23+
1824
import org.springframework.data.cassandra.core.cql.Ordering;
1925
import org.springframework.data.mapping.model.Property;
2026
import org.springframework.data.mapping.model.SimpleTypeHolder;
@@ -36,6 +42,7 @@ public class CachingCassandraPersistentProperty extends BasicCassandraPersistent
3642
private final boolean isPrimaryKeyColumn;
3743
private final boolean isEmbedded;
3844
private final boolean isStaticColumn;
45+
private final Map<Class<? extends Annotation>, Optional<AnnotatedType>> findAnnotatedTypeCache = new ConcurrentHashMap<>();
3946

4047
public CachingCassandraPersistentProperty(Property property, CassandraPersistentEntity<?> owner,
4148
SimpleTypeHolder simpleTypeHolder) {
@@ -106,4 +113,13 @@ public boolean isStaticColumn() {
106113
public boolean isEmbedded() {
107114
return isEmbedded;
108115
}
116+
117+
/* (non-Javadoc)
118+
* @see org.springframework.data.cassandra.core.mapping.BasicCassandraPersistentProperty#findAnnotatedType(Class)
119+
*/
120+
@Override
121+
public AnnotatedType findAnnotatedType(Class<? extends Annotation> annotationType) {
122+
return findAnnotatedTypeCache
123+
.computeIfAbsent(annotationType, key -> Optional.ofNullable(super.findAnnotatedType(key))).orElse(null);
124+
}
109125
}

0 commit comments

Comments
 (0)