From af8f2da6f268b3497922dd91d2c197714d25a6ca Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Wed, 14 Dec 2022 22:46:30 +0000 Subject: [PATCH] HHH-15873 Micro optimisations of FetchParent#findFetch(Fetchable) operations --- .../internal/CompoundNaturalIdMapping.java | 3 +- .../DiscriminatedAssociationMapping.java | 9 +++--- .../results/complete/EntityResultImpl.java | 17 ++++++----- .../results/graph/AbstractFetchParent.java | 30 ++++++++++++++----- .../internal/EagerCollectionFetch.java | 3 +- .../AggregateEmbeddableFetchImpl.java | 3 +- .../AggregateEmbeddableResultImpl.java | 4 +-- .../EmbeddableExpressionResultImpl.java | 2 +- .../EmbeddableForeignKeyResultImpl.java | 7 +---- .../internal/EmbeddableResultImpl.java | 2 +- 10 files changed, 46 insertions(+), 34 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CompoundNaturalIdMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CompoundNaturalIdMapping.java index 1ef0637536..66b26e5a3b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CompoundNaturalIdMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CompoundNaturalIdMapping.java @@ -8,6 +8,7 @@ package org.hibernate.metamodel.mapping.internal; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.BiConsumer; @@ -467,7 +468,7 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement this.arrayJtd = arrayJtd; this.resultVariable = resultVariable; - this.fetches = creationState.visitFetches( this ); + this.fetches = Collections.unmodifiableList( creationState.visitFetches( this ) ); } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/DiscriminatedAssociationMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/DiscriminatedAssociationMapping.java index ab69d0d7d0..625963d76b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/DiscriminatedAssociationMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/DiscriminatedAssociationMapping.java @@ -7,6 +7,7 @@ package org.hibernate.metamodel.mapping.internal; import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -412,6 +413,7 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption private Fetch discriminatorValueFetch; private Fetch keyValueFetch; + private List fetches; public AnyValuedResultGraphNode( NavigablePath navigablePath, @@ -423,7 +425,7 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption } protected void afterInitialize(DomainResultCreationState creationState) { - final List fetches = creationState.visitFetches( this ); + this.fetches = Collections.unmodifiableList( creationState.visitFetches( this ) ); assert fetches.size() == 2; discriminatorValueFetch = fetches.get( 0 ); @@ -469,14 +471,11 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption @Override public List getFetches() { - return Arrays.asList( discriminatorValueFetch, keyValueFetch ); + return fetches; } @Override public Fetch findFetch(Fetchable fetchable) { - assert graphedPart.getDiscriminatorPart() == fetchable - || graphedPart.getKeyPart() == fetchable; - if ( graphedPart.getDiscriminatorPart() == fetchable ) { return discriminatorValueFetch; } diff --git a/hibernate-core/src/main/java/org/hibernate/query/results/complete/EntityResultImpl.java b/hibernate-core/src/main/java/org/hibernate/query/results/complete/EntityResultImpl.java index 6be6423eed..1f2a557234 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/results/complete/EntityResultImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/results/complete/EntityResultImpl.java @@ -6,6 +6,7 @@ */ package org.hibernate.query.results.complete; +import java.util.Collections; import java.util.List; import java.util.function.Function; @@ -79,7 +80,7 @@ public class EntityResultImpl implements EntityResult { this.discriminatorFetch = discriminatorFetchBuilder.apply( this ); - this.fetches = creationState.visitFetches( this ); + final List localFetches = creationState.visitFetches( this ); final EntityIdentifierMapping identifierMapping = entityValuedModelPart .getEntityMappingType() @@ -90,18 +91,19 @@ public class EntityResultImpl implements EntityResult { final MutableObject idFetchRef = new MutableObject<>(); - for ( int i = 0; i < this.fetches.size(); i++ ) { - final Fetch fetch = this.fetches.get( i ); + for ( int i = 0; i < localFetches.size(); i++ ) { + final Fetch fetch = localFetches.get( i ); final String fetchLocalName = fetch.getNavigablePath().getLocalName(); if ( fetchLocalName.equals( EntityIdentifierMapping.ROLE_LOCAL_NAME ) || ( idAttributeName != null && fetchLocalName.equals( idAttributeName ) ) ) { // we found the id fetch idFetchRef.set( fetch ); - this.fetches.remove( i ); + localFetches.remove( i ); break; } } + this.fetches = Collections.unmodifiableList( localFetches ); if ( idFetchRef.isNotSet() ) { identifierFetch = ( (Fetchable) identifierMapping ).generateFetch( @@ -148,12 +150,13 @@ public class EntityResultImpl implements EntityResult { @Override public Fetch findFetch(Fetchable fetchable) { + final String name = fetchable.getFetchableName(); for ( int i = 0; i < fetches.size(); i++ ) { - if ( fetches.get( i ).getFetchedMapping().getFetchableName().equals( fetchable.getFetchableName() ) ) { - return fetches.get( i ); + final Fetch fetch = fetches.get( i ); + if ( fetch.getFetchedMapping().getFetchableName().equals( name ) ) { + return fetch; } } - return null; } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/AbstractFetchParent.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/AbstractFetchParent.java index a7d00582d9..976bea6dd9 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/AbstractFetchParent.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/AbstractFetchParent.java @@ -10,6 +10,7 @@ import java.util.Collections; import java.util.List; import org.hibernate.metamodel.mapping.EntityVersionMapping; +import org.hibernate.metamodel.model.domain.NavigableRole; import org.hibernate.spi.NavigablePath; import org.hibernate.type.descriptor.java.JavaType; @@ -20,7 +21,7 @@ public abstract class AbstractFetchParent implements FetchParent { private final FetchableContainer fetchContainer; private final NavigablePath navigablePath; - protected List fetches; + private List fetches; public AbstractFetchParent(FetchableContainer fetchContainer, NavigablePath navigablePath) { this.fetchContainer = fetchContainer; @@ -29,7 +30,11 @@ public abstract class AbstractFetchParent implements FetchParent { public void afterInitialize(FetchParent fetchParent, DomainResultCreationState creationState) { assert fetches == null; - this.fetches = creationState.visitFetches( fetchParent ); + resetFetches( creationState.visitFetches( fetchParent ) ); + } + + protected void resetFetches(final List newFetches) { + this.fetches = Collections.unmodifiableList( newFetches ); } public FetchableContainer getFetchContainer() { @@ -53,25 +58,34 @@ public abstract class AbstractFetchParent implements FetchParent { @Override public List getFetches() { - return fetches == null ? Collections.emptyList() : Collections.unmodifiableList( fetches ); + return fetches == null ? Collections.emptyList() : fetches; } @Override - public Fetch findFetch(Fetchable fetchable) { + public Fetch findFetch(final Fetchable fetchable) { if ( fetches == null ) { return null; } + //Iterate twice so we can perform the cheapest checks on each item first: for ( int i = 0; i < fetches.size(); i++ ) { final Fetch fetch = fetches.get( i ); - final Fetchable fetchedMapping = fetch.getFetchedMapping(); - if ( fetchedMapping == fetchable - // the fetched mapping for the version is a Basic attribute, so check the role - || ( fetchable instanceof EntityVersionMapping && fetchable.getNavigableRole().equals( fetchedMapping.getNavigableRole() ) ) ) { + if ( fetchable == fetch.getFetchedMapping() ) { return fetch; } } + if ( fetchable instanceof EntityVersionMapping ) { + //Second iteration performs the slightly more expensive checks, necessary for EntityVersionMapping: + final NavigableRole navigableRole = fetchable.getNavigableRole(); + for ( int i = 0; i < fetches.size(); i++ ) { + final Fetch fetch = fetches.get( i ); + if ( fetch.getFetchedMapping().getNavigableRole().equals( navigableRole ) ) { + return fetch; + } + } + } + return null; } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/EagerCollectionFetch.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/EagerCollectionFetch.java index 8ce8aa9d7f..4dafb49d79 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/EagerCollectionFetch.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/EagerCollectionFetch.java @@ -6,6 +6,7 @@ */ package org.hibernate.sql.results.graph.collection.internal; +import java.util.Collections; import java.util.List; import org.hibernate.collection.spi.CollectionInitializerProducer; @@ -103,7 +104,7 @@ public class EagerCollectionFetch extends CollectionFetch implements FetchParent creationState ); - fetches = creationState.visitFetches( this ); + fetches = Collections.unmodifiableList( creationState.visitFetches( this ) ); if ( fetchedAttribute.getIndexDescriptor() != null ) { assert fetches.size() == 2; indexFetch = fetches.get( 0 ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/AggregateEmbeddableFetchImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/AggregateEmbeddableFetchImpl.java index 680aef4685..2e1e725ad4 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/AggregateEmbeddableFetchImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/AggregateEmbeddableFetchImpl.java @@ -31,7 +31,6 @@ import org.hibernate.sql.results.graph.Fetchable; import org.hibernate.sql.results.graph.embeddable.EmbeddableInitializer; import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode; import org.hibernate.sql.results.graph.embeddable.EmbeddableValuedFetchable; -import org.hibernate.type.descriptor.jdbc.AggregateJdbcType; import org.hibernate.type.spi.TypeConfiguration; /** @@ -95,7 +94,7 @@ public class AggregateEmbeddableFetchImpl extends AbstractFetchParent implements fetchParent, typeConfiguration ); - this.fetches = creationState.visitNestedFetches( this ); + resetFetches( creationState.visitNestedFetches( this ) ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/AggregateEmbeddableResultImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/AggregateEmbeddableResultImpl.java index 76b0cd9eb8..0a99e7af09 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/AggregateEmbeddableResultImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/AggregateEmbeddableResultImpl.java @@ -102,8 +102,8 @@ public class AggregateEmbeddableResultImpl extends AbstractFetchParent implem null, typeConfiguration ); - this.fetches = creationState.visitNestedFetches( this ); - this.containsAnyNonScalars = determineIfContainedAnyScalars( fetches ); + resetFetches( creationState.visitNestedFetches( this ) ); + this.containsAnyNonScalars = determineIfContainedAnyScalars( getFetches() ); } private static boolean determineIfContainedAnyScalars(List fetches) { diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/EmbeddableExpressionResultImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/EmbeddableExpressionResultImpl.java index 8485995982..98b0c9b350 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/EmbeddableExpressionResultImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/EmbeddableExpressionResultImpl.java @@ -81,8 +81,8 @@ public class EmbeddableExpressionResultImpl extends AbstractFetchParent imple ); } - this.fetches = fetches; this.containsAnyNonScalars = determineIfContainedAnyScalars( fetches ); + resetFetches( fetches ); } private static boolean determineIfContainedAnyScalars(List fetches) { diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/EmbeddableForeignKeyResultImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/EmbeddableForeignKeyResultImpl.java index a94b782b8b..0bcfeb1293 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/EmbeddableForeignKeyResultImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/EmbeddableForeignKeyResultImpl.java @@ -43,7 +43,7 @@ public class EmbeddableForeignKeyResultImpl super( embeddableValuedModelPart.getEmbeddableTypeDescriptor(), navigablePath ); this.resultVariable = resultVariable; this.fetchParent = fetchParent; - this.fetches = creationState.visitFetches( this ); + resetFetches( creationState.visitFetches( this ) ); } @Override @@ -110,11 +110,6 @@ public class EmbeddableForeignKeyResultImpl return (EmbeddableMappingType) getFetchContainer().getPartMappingType(); } - @Override - public Fetch findFetch(Fetchable fetchable) { - return super.findFetch( fetchable ); - } - @Override public EmbeddableMappingType getFetchContainer() { return (EmbeddableMappingType) super.getFetchContainer(); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/EmbeddableResultImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/EmbeddableResultImpl.java index 1577156559..a9ddf1c867 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/EmbeddableResultImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/internal/EmbeddableResultImpl.java @@ -73,7 +73,7 @@ public class EmbeddableResultImpl extends AbstractFetchParent implements Embe afterInitialize( this, creationState ); // after-after-initialize :D - containsAnyNonScalars = determineIfContainedAnyScalars( fetches ); + containsAnyNonScalars = determineIfContainedAnyScalars( getFetches() ); } private static boolean determineIfContainedAnyScalars(List fetches) {