From 43af5343a43ef98ce233634ba99d2b052fa59115 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 2 Feb 2022 12:10:02 +1300 Subject: [PATCH] Performance - cache the path maps used for load context - Cache the path maps - Include the ToOne paths - Use empty map for null prefix --- .../server/deploy/BeanDescriptor.java | 18 ++++++++++++++++++ .../io/ebeaninternal/server/query/CQuery.java | 14 +++++--------- .../ebeaninternal/server/query/STreeType.java | 6 ++++++ .../server/query/SqlTreeNodeBean.java | 13 ++----------- 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index eba1eea95..c06dfce3e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -86,6 +86,8 @@ public class BeanDescriptor implements BeanType, STreeType, SpiBeanType { private final ConcurrentHashMap elDeployCache = new ConcurrentHashMap<>(); private final ConcurrentHashMap> comparatorCache = new ConcurrentHashMap<>(); private final ConcurrentHashMap dynamicProperty = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> pathMaps = new ConcurrentHashMap<>(); + private final Map namedRawSql; private final Map namedQuery; private final boolean multiValueSupported; @@ -2775,6 +2777,22 @@ public class BeanDescriptor implements BeanType, STreeType, SpiBeanType { return draftableElement; } + @Override + public Map pathMap(String prefix) { + return pathMaps.computeIfAbsent(prefix, s -> { + HashMap m = new HashMap<>(); + for (STreePropertyAssocMany many : propsMany()) { + String name = many.name(); + m.put(name, prefix + "." + name); + } + for (STreePropertyAssocOne one : propsOne()) { + String name = one.name(); + m.put(name, prefix + "." + name); + } + return m.isEmpty() ? Collections.emptyMap() : m; + }); + } + @Override public boolean isEmbeddedPath(String propertyPath) { ElPropertyDeploy elProp = elPropertyDeploy(propertyPath); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java index 1870c1b6f..634591fec 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java @@ -581,19 +581,19 @@ public final class CQuery implements DbReadContext, CancelableQuery, SpiProfi @Override public void registerBeanInherit(BeanPropertyAssocOne property, EntityBeanIntercept ebi) { - String path = getPath(property.name()); + String path = path(property.name()); request.loadContext().register(path, ebi, property); } @Override public void register(String path, EntityBeanIntercept ebi) { - path = getPath(path); + path = path(path); request.loadContext().register(path, ebi); } @Override public void register(BeanPropertyAssocMany many, BeanCollection bc) { - String path = getPath(many.name()); + String path = path(many.name()); request.loadContext().register(path, many, bc); } @@ -663,18 +663,14 @@ public final class CQuery implements DbReadContext, CancelableQuery, SpiProfi return autoTuneProfiling && query.isUsageProfiling(); } - private String getPath(String propertyName) { + private String path(String propertyName) { if (currentPrefix == null) { return propertyName; } else if (propertyName == null) { return currentPrefix; } String path = currentPathMap.get(propertyName); - if (path != null) { - return path; - } else { - return currentPrefix + "." + propertyName; - } + return path != null ? path : currentPrefix + "." + propertyName; } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/STreeType.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/STreeType.java index 3bb58dd1c..88e3b851a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/STreeType.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/STreeType.java @@ -7,6 +7,8 @@ import io.ebeaninternal.server.deploy.DbReadContext; import io.ebeaninternal.server.deploy.InheritInfo; import io.ebeaninternal.server.deploy.id.IdBinder; +import java.util.Map; + /** * Bean type interface for Sql query tree. */ @@ -136,4 +138,8 @@ public interface STreeType { */ void markAsDeleted(EntityBean bean); + /** + * Return the "path map" to toMany or toOne properties using the given prefix. + */ + Map pathMap(String prefix); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java index 6c62116fc..d5ec71aa4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java @@ -122,20 +122,11 @@ class SqlTreeNodeBean implements SqlTreeNode { } private Map createPathMap(String prefix, STreeType desc) { - HashMap m = new HashMap<>(); - for (STreePropertyAssocMany many : desc.propsMany()) { - String name = many.name(); - m.put(name, path(prefix, name)); - } - return m; + return prefix == null ? Collections.emptyMap() : desc.pathMap(prefix); } private String path(String prefix, String propertyName) { - if (prefix == null) { - return propertyName; - } else { - return prefix + "." + propertyName; - } + return prefix == null ? propertyName : prefix + "." + propertyName; } @Override