HHH-15873 Micro optimisations of FetchParent#findFetch(Fetchable) operations

This commit is contained in:
Sanne Grinovero 2022-12-14 22:46:30 +00:00 committed by Sanne Grinovero
parent fc7bdce2c8
commit af8f2da6f2
10 changed files with 46 additions and 34 deletions

View File

@ -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 ) );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -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<Fetch> fetches;
public AnyValuedResultGraphNode(
NavigablePath navigablePath,
@ -423,7 +425,7 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
}
protected void afterInitialize(DomainResultCreationState creationState) {
final List<Fetch> 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<Fetch> 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;
}

View File

@ -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<Fetch> localFetches = creationState.visitFetches( this );
final EntityIdentifierMapping identifierMapping = entityValuedModelPart
.getEntityMappingType()
@ -90,18 +91,19 @@ public class EntityResultImpl implements EntityResult {
final MutableObject<Fetch> 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;
}

View File

@ -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<Fetch> fetches;
private List<Fetch> 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<Fetch> newFetches) {
this.fetches = Collections.unmodifiableList( newFetches );
}
public FetchableContainer getFetchContainer() {
@ -53,25 +58,34 @@ public abstract class AbstractFetchParent implements FetchParent {
@Override
public List<Fetch> 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;
}
}

View File

@ -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 );

View File

@ -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

View File

@ -102,8 +102,8 @@ public class AggregateEmbeddableResultImpl<T> 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<Fetch> fetches) {

View File

@ -81,8 +81,8 @@ public class EmbeddableExpressionResultImpl<T> extends AbstractFetchParent imple
);
}
this.fetches = fetches;
this.containsAnyNonScalars = determineIfContainedAnyScalars( fetches );
resetFetches( fetches );
}
private static boolean determineIfContainedAnyScalars(List<Fetch> fetches) {

View File

@ -43,7 +43,7 @@ public class EmbeddableForeignKeyResultImpl<T>
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<T>
return (EmbeddableMappingType) getFetchContainer().getPartMappingType();
}
@Override
public Fetch findFetch(Fetchable fetchable) {
return super.findFetch( fetchable );
}
@Override
public EmbeddableMappingType getFetchContainer() {
return (EmbeddableMappingType) super.getFetchContainer();

View File

@ -73,7 +73,7 @@ public class EmbeddableResultImpl<T> extends AbstractFetchParent implements Embe
afterInitialize( this, creationState );
// after-after-initialize :D
containsAnyNonScalars = determineIfContainedAnyScalars( fetches );
containsAnyNonScalars = determineIfContainedAnyScalars( getFetches() );
}
private static boolean determineIfContainedAnyScalars(List<Fetch> fetches) {