Skip to content

Commit

Permalink
Avoid records as cache keys for performance reasons.
Browse files Browse the repository at this point in the history
Fixes GH-2997.
  • Loading branch information
odrotbohm committed Dec 5, 2023
1 parent 6e22ffd commit 0cf2538
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 20 deletions.
44 changes: 40 additions & 4 deletions src/main/java/org/springframework/data/mapping/PropertyPath.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ public class PropertyPath implements Streamable<PropertyPath> {
}

this.owningType = owningType;
this.name = property.path();
this.typeInformation = property.type();
this.name = property.path;
this.typeInformation = property.type;
this.isCollection = this.typeInformation.isCollectionLike();
this.actualTypeInformation = this.typeInformation.getActualType() == null ? this.typeInformation
: this.typeInformation.getRequiredActualType();
Expand Down Expand Up @@ -499,6 +499,42 @@ public String toString() {
return String.format("%s.%s", owningType.getType().getSimpleName(), toDotPath());
}

private record Property(TypeInformation<?> type, String path) {
};
private static final class Property {

private final TypeInformation<?> type;
private final String path;

private Property(TypeInformation<?> type, String path) {
this.type = type;
this.path = path;
}

@Override
public boolean equals(@Nullable Object obj) {

if (obj == this) {
return true;
}

if (!(obj instanceof Property that)) {
return false;
}

return Objects.equals(this.type, that.type) &&
Objects.equals(this.path, that.path);
}

@Override
public int hashCode() {
return Objects.hash(type, path);
}

@Override
public String toString() {

return "Key[" +
"type=" + type + ", " +
"path=" + path + ']';
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
Expand Down Expand Up @@ -331,7 +332,7 @@ void discoverEntityCallbacks(BeanFactory beanFactory) {
*
* @author Oliver Drotbohm
*/
private record EntityCallbackAdapter<T> (EntityCallback<T> delegate,
private record EntityCallbackAdapter<T>(EntityCallback<T> delegate,
ResolvableType type) implements EntityCallback<T> {

boolean supports(ResolvableType callbackType, ResolvableType entityType) {
Expand All @@ -342,17 +343,52 @@ boolean supports(ResolvableType callbackType, ResolvableType entityType) {
/**
* Cache key for {@link EntityCallback}, based on event type and source type.
*/
private record CallbackCacheKey(ResolvableType callbackType,
@Nullable Class<?> entityType) implements Comparable<CallbackCacheKey> {
private static final class CallbackCacheKey implements Comparable<CallbackCacheKey> {

private static final Comparator<CallbackCacheKey> COMPARATOR = Comparators.<CallbackCacheKey> nullsHigh() //
.thenComparing(it -> it.callbackType.toString()) //
.thenComparing(it -> it.entityType.getName());

private final ResolvableType callbackType;
private final Class<?> entityType;

private CallbackCacheKey(ResolvableType callbackType, Class<?> entityType) {

this.callbackType = callbackType;
this.entityType = entityType;
}

@Override
public int compareTo(CallbackCacheKey other) {
public int compareTo(@Nullable CallbackCacheKey other) {
return COMPARATOR.compare(this, other);
}
}

@Override
public boolean equals(@Nullable Object obj) {

if (obj == this) {
return true;
}

if (!(obj instanceof CallbackCacheKey that)) {
return false;
}

return Objects.equals(this.callbackType, that.callbackType)
&& Objects.equals(this.entityType, that.entityType);
}

@Override
public int hashCode() {
return Objects.hash(callbackType, entityType);
}

@Override
public String toString() {

return "CallbackCacheKey[" +
"callbackType=" + callbackType + ", " +
"entityType=" + entityType + ']';
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,7 @@
*/
package org.springframework.data.mapping.context;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -279,12 +270,55 @@ private Collection<PersistentPropertyPath<P>> from(E entity, Predicate<? super P
return properties;
}

record TypeAndPath(TypeInformation<?> type, String path) {
static final class TypeAndPath {

private final TypeInformation<?> type;
private final String path;

private TypeAndPath(TypeInformation<?> type, String path) {
this.type = type;
this.path = path;
}

public static TypeAndPath of(TypeInformation<?> type, String path) {
return new TypeAndPath(type, path);
}

public TypeInformation<?> type() {
return type;
}

public String path() {
return path;
}

@Override
public boolean equals(@Nullable Object obj) {

if (obj == this) {
return true;
}

if (!(obj instanceof TypeAndPath that)) {
return false;
}

return Objects.equals(this.type, that.type)
&& Objects.equals(this.path, that.path);
}

@Override
public int hashCode() {
return Objects.hash(type, path);
}

@Override
public String toString() {

return "TypeAndPath[" +
"type=" + type + ", " +
"path=" + path + ']';
}
}

static class DefaultPersistentPropertyPaths<T, P extends PersistentProperty<P>>
Expand Down

0 comments on commit 0cf2538

Please sign in to comment.