Skip to content

Commit 2b49f2c

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 e6ef5ca commit 2b49f2c

File tree

4 files changed

+44
-3
lines changed

4 files changed

+44
-3
lines changed

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

Lines changed: 26 additions & 1 deletion
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);
@@ -165,7 +180,17 @@ private boolean isFrozen(AnnotatedType type) {
165180

166181
@Override
167182
public CassandraColumnType resolve(TypeInformation<?> typeInformation) {
168-
return resolve(typeInformation, FrozenIndicator.NOT_FROZEN);
183+
184+
Assert.notNull(typeInformation, "TypeInformation must not be null");
185+
186+
CassandraColumnType cassandraColumnType = typeInformationColumnTypeCache.get(typeInformation);
187+
if (cassandraColumnType == null) {
188+
// avoid recursive update
189+
cassandraColumnType = resolve(typeInformation, FrozenIndicator.NOT_FROZEN);
190+
typeInformationColumnTypeCache.put(typeInformation, cassandraColumnType);
191+
}
192+
193+
return cassandraColumnType;
169194
}
170195

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

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,8 @@ protected Object getPotentiallyConvertedSimpleRead(Object value, TypeInformation
10311031
@SuppressWarnings({ "rawtypes", "unchecked" })
10321032
private Object getPotentiallyConvertedSimpleRead(Object value, @Nullable Class<?> target) {
10331033

1034-
if (value == null || target == null || target.isAssignableFrom(value.getClass())) {
1034+
if (value == null || target == null
1035+
|| ClassUtils.resolvePrimitiveIfNecessary(target).isAssignableFrom(value.getClass())) {
10351036
return value;
10361037
}
10371038

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ public CqlIdentifier getColumnName() {
105105
this.columnName = determineColumnName();
106106
}
107107

108-
Assert.state(this.columnName != null, () -> String.format("Cannot determine column name for %s", this));
108+
if (columnName == null) {
109+
throw new IllegalStateException(String.format("Cannot determine column name for %s", this));
110+
}
109111

110112
return this.columnName;
111113
}

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

Lines changed: 13 additions & 0 deletions
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) {
@@ -85,4 +92,10 @@ public boolean isStaticColumn() {
8592
public boolean isEmbedded() {
8693
return isEmbedded;
8794
}
95+
96+
@Override
97+
public AnnotatedType findAnnotatedType(Class<? extends Annotation> annotationType) {
98+
return findAnnotatedTypeCache
99+
.computeIfAbsent(annotationType, key -> Optional.ofNullable(super.findAnnotatedType(key))).orElse(null);
100+
}
88101
}

0 commit comments

Comments
 (0)