(perf) fix cases of Map resizing when number of entries known ahead of time;
(perf) convert some List Iterators to "for i" loops
This commit is contained in:
parent
5482c55e6c
commit
1a3fcff8af
|
@ -716,8 +716,9 @@ public abstract class SimpleValue implements KeyValue {
|
|||
|
||||
@Override
|
||||
public boolean hasAnyInsertableColumns() {
|
||||
for ( Boolean val : insertability ) {
|
||||
if ( val ) {
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for ( int i = 0; i < insertability.size(); i++ ) {
|
||||
if ( insertability.get( i ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -732,8 +733,8 @@ public abstract class SimpleValue implements KeyValue {
|
|||
|
||||
@Override
|
||||
public boolean hasAnyUpdatableColumns() {
|
||||
for ( Boolean val : updatability ) {
|
||||
if ( val ) {
|
||||
for ( int i = 0; i < updatability.size(); i++ ) {
|
||||
if ( updatability.get( i ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
|||
public class OptimizedPojoInstantiatorImpl<J> extends AbstractPojoInstantiator {
|
||||
private final ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer;
|
||||
|
||||
public OptimizedPojoInstantiatorImpl(JavaTypeDescriptor javaTypeDescriptor, ReflectionOptimizer reflectionOptimizer) {
|
||||
public OptimizedPojoInstantiatorImpl(JavaTypeDescriptor javaTypeDescriptor, ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer) {
|
||||
super( javaTypeDescriptor.getJavaType() );
|
||||
this.instantiationOptimizer = reflectionOptimizer.getInstantiationOptimizer();
|
||||
this.instantiationOptimizer = instantiationOptimizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -38,6 +38,7 @@ public class StandardPojoEmbeddableRepresentationStrategy extends AbstractEmbedd
|
|||
public StandardPojoEmbeddableRepresentationStrategy(
|
||||
Component bootDescriptor,
|
||||
RuntimeModelCreationContext creationContext) {
|
||||
//noinspection unchecked
|
||||
super(
|
||||
bootDescriptor,
|
||||
creationContext.getTypeConfiguration()
|
||||
|
@ -55,7 +56,10 @@ public class StandardPojoEmbeddableRepresentationStrategy extends AbstractEmbedd
|
|||
this.reflectionOptimizer = buildReflectionOptimizer( bootDescriptor, creationContext );
|
||||
|
||||
if ( reflectionOptimizer != null && reflectionOptimizer.getInstantiationOptimizer() != null ) {
|
||||
this.instantiator = new OptimizedPojoInstantiatorImpl<>( getEmbeddableJavaTypeDescriptor(), reflectionOptimizer );
|
||||
final ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer = reflectionOptimizer.getInstantiationOptimizer();
|
||||
this.instantiator = instantiationOptimizer != null
|
||||
? new OptimizedPojoInstantiatorImpl<>( getEmbeddableJavaTypeDescriptor(), instantiationOptimizer )
|
||||
: new PojoInstantiatorImpl<>( getEmbeddableJavaTypeDescriptor() );
|
||||
}
|
||||
else {
|
||||
this.instantiator = new PojoInstantiatorImpl<>( getEmbeddableJavaTypeDescriptor() );
|
||||
|
|
|
@ -108,10 +108,16 @@ public class StandardPojoEntityRepresentationStrategy implements EntityRepresent
|
|||
|
||||
this.proxyFactory = createProxyFactory( bootDescriptor, bytecodeProvider, creationContext );
|
||||
|
||||
this.reflectionOptimizer = resolveReflectionOptimizer( bootDescriptor, bytecodeProvider );
|
||||
this.reflectionOptimizer = resolveReflectionOptimizer( bootDescriptor, bytecodeProvider, sessionFactory );
|
||||
|
||||
if ( reflectionOptimizer != null && reflectionOptimizer.getInstantiationOptimizer() != null ) {
|
||||
this.instantiator = new OptimizedPojoInstantiatorImpl<>( mappedJtd, reflectionOptimizer );
|
||||
if ( reflectionOptimizer != null ) {
|
||||
final ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer = reflectionOptimizer.getInstantiationOptimizer();
|
||||
if ( instantiationOptimizer != null ) {
|
||||
this.instantiator = new OptimizedPojoInstantiatorImpl<>( mappedJtd, instantiationOptimizer );
|
||||
}
|
||||
else {
|
||||
this.instantiator = new PojoInstantiatorImpl<>( mappedJtd );
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.instantiator = new PojoInstantiatorImpl<>( mappedJtd );
|
||||
|
@ -226,7 +232,8 @@ public class StandardPojoEntityRepresentationStrategy implements EntityRepresent
|
|||
|
||||
private ReflectionOptimizer resolveReflectionOptimizer(
|
||||
PersistentClass bootType,
|
||||
BytecodeProvider bytecodeProvider) {
|
||||
BytecodeProvider bytecodeProvider,
|
||||
@SuppressWarnings("unused") SessionFactoryImplementor sessionFactory) {
|
||||
final Class javaTypeToReflect;
|
||||
if ( proxyFactory != null ) {
|
||||
assert proxyJtd != null;
|
||||
|
|
|
@ -27,6 +27,16 @@ public class QueryInterpretationCacheDisabledImpl implements QueryInterpretation
|
|||
*/
|
||||
public static final QueryInterpretationCacheDisabledImpl INSTANCE = new QueryInterpretationCacheDisabledImpl();
|
||||
|
||||
@Override
|
||||
public int getNumberOfCachedHqlInterpretations() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfCachedQueryPlans() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectQueryPlan resolveSelectQueryPlan(Key key, Supplier<SelectQueryPlan> creator) {
|
||||
return null;
|
||||
|
|
|
@ -61,6 +61,16 @@ public class QueryInterpretationCacheStandardImpl implements QueryInterpretation
|
|||
nativeQueryParamCache = new BoundedConcurrentHashMap<>( maxQueryPlanCount, 20, BoundedConcurrentHashMap.Eviction.LIRS );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfCachedHqlInterpretations() {
|
||||
return hqlInterpretationCache.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfCachedQueryPlans() {
|
||||
return queryPlanCache.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectQueryPlan resolveSelectQueryPlan(
|
||||
Key key,
|
||||
|
|
|
@ -11,6 +11,6 @@ import org.hibernate.sql.exec.spi.ExecutionContext;
|
|||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface NonSelectQueryPlan {
|
||||
public interface NonSelectQueryPlan extends QueryPlan {
|
||||
int executeUpdate(ExecutionContext executionContext);
|
||||
}
|
||||
|
|
|
@ -23,16 +23,16 @@ public interface QueryInterpretationCache {
|
|||
interface Key {
|
||||
}
|
||||
|
||||
int getNumberOfCachedHqlInterpretations();
|
||||
int getNumberOfCachedQueryPlans();
|
||||
|
||||
HqlInterpretation resolveHqlInterpretation(String queryString, Function<String, SqmStatement<?>> creator);
|
||||
|
||||
SelectQueryPlan resolveSelectQueryPlan(Key key, Supplier<SelectQueryPlan> creator);
|
||||
|
||||
NonSelectQueryPlan getNonSelectQueryPlan(Key key);
|
||||
void cacheNonSelectQueryPlan(Key key, NonSelectQueryPlan plan);
|
||||
|
||||
/**
|
||||
* todo (6.0) : Doesn't holding these separate from the QueryPlans lead to extra, unnecessary memory use?
|
||||
*/
|
||||
HqlInterpretation resolveHqlInterpretation(String queryString, Function<String, SqmStatement<?>> creator);
|
||||
|
||||
ParameterInterpretation resolveNativeQueryParameters(String queryString, Function<String, ParameterInterpretation> creator);
|
||||
|
||||
boolean isEnabled();
|
||||
|
|
|
@ -43,9 +43,11 @@ public class SqmInterpretationsKey implements QueryInterpretationCache.Key {
|
|||
|
||||
@SuppressWarnings("RedundantIfStatement")
|
||||
private static boolean isCacheable(QuerySqmImpl<?> query) {
|
||||
if ( query.getQueryOptions().getAppliedGraph() != null ) {
|
||||
assert query.getQueryOptions().getAppliedGraph() != null;
|
||||
|
||||
if ( query.getQueryOptions().getAppliedGraph().getSemantic() != null ) {
|
||||
// At the moment we cannot cache query plan if there is an
|
||||
// EntityGraph involved.
|
||||
// EntityGraph enabled.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,11 +8,10 @@ package org.hibernate.sql.exec.internal;
|
|||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.query.sqm.internal.DomainParameterXref;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameter;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameterBinding;
|
||||
|
@ -28,14 +27,14 @@ public class JdbcParameterBindingsImpl implements JdbcParameterBindings {
|
|||
|
||||
public JdbcParameterBindingsImpl(DomainParameterXref domainParameterXref) {
|
||||
if ( domainParameterXref.getSqmParameterCount() > 0 ) {
|
||||
bindingMap = CollectionHelper.mapOfSize( domainParameterXref.getSqmParameterCount() );
|
||||
bindingMap = new IdentityHashMap<>( domainParameterXref.getSqmParameterCount() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBinding(JdbcParameter parameter, JdbcParameterBinding binding) {
|
||||
if ( bindingMap == null ) {
|
||||
bindingMap = new HashMap<>();
|
||||
bindingMap = new IdentityHashMap<>();
|
||||
}
|
||||
|
||||
bindingMap.put( parameter, binding );
|
||||
|
|
|
@ -7,16 +7,13 @@
|
|||
package org.hibernate.sql.results.internal;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.loader.plan.spi.EntityFetch;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.exec.spi.Callback;
|
||||
import org.hibernate.sql.exec.spi.DomainParameterBindingContext;
|
||||
import org.hibernate.sql.results.spi.Initializer;
|
||||
|
@ -32,11 +29,12 @@ import org.jboss.logging.Logger;
|
|||
*/
|
||||
public class RowProcessingStateStandardImpl implements RowProcessingState {
|
||||
private static final Logger log = Logger.getLogger( RowProcessingStateStandardImpl.class );
|
||||
private static final Initializer[] NO_INITIALIZERS = new Initializer[0];
|
||||
|
||||
private final JdbcValuesSourceProcessingStateStandardImpl resultSetProcessingState;
|
||||
private final QueryOptions queryOptions;
|
||||
|
||||
private final Map<NavigablePath, Initializer> initializerMap;
|
||||
private final Initializer[] initializers;
|
||||
|
||||
private final JdbcValues jdbcValues;
|
||||
private Object[] currentRowJdbcValues;
|
||||
|
@ -52,14 +50,11 @@ public class RowProcessingStateStandardImpl implements RowProcessingState {
|
|||
|
||||
final List<Initializer> initializers = rowReader.getInitializers();
|
||||
if ( initializers == null || initializers.isEmpty() ) {
|
||||
initializerMap = null;
|
||||
this.initializers = NO_INITIALIZERS;
|
||||
}
|
||||
else {
|
||||
initializerMap = new HashMap<>();
|
||||
for ( Initializer initializer : initializers ) {
|
||||
initializerMap.put( initializer.getNavigablePath(), initializer );
|
||||
}
|
||||
|
||||
//noinspection ToArrayCallWithZeroLengthArrayArgument
|
||||
this.initializers = initializers.toArray( new Initializer[initializers.size()] );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,6 +110,12 @@ public class RowProcessingStateStandardImpl implements RowProcessingState {
|
|||
|
||||
@Override
|
||||
public Initializer resolveInitializer(NavigablePath path) {
|
||||
return initializerMap == null ? null : initializerMap.get( path );
|
||||
for ( Initializer initializer : initializers ) {
|
||||
if ( initializer.getNavigablePath().equals( path ) ) {
|
||||
return initializer;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,8 +48,9 @@ public class StandardJdbcValuesMapping implements JdbcValuesMapping {
|
|||
AssemblerCreationState creationState) {
|
||||
final List<DomainResultAssembler> assemblers = CollectionHelper.arrayList( domainResults.size() );
|
||||
|
||||
for ( DomainResult domainResult : domainResults ) {
|
||||
final DomainResultAssembler resultAssembler = domainResult.createResultAssembler(
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for ( int i = 0; i < domainResults.size(); i++ ) {
|
||||
final DomainResultAssembler resultAssembler = domainResults.get( i ).createResultAssembler(
|
||||
initializerConsumer,
|
||||
creationState
|
||||
);
|
||||
|
|
|
@ -6,11 +6,10 @@
|
|||
*/
|
||||
package org.hibernate.sql.results.internal.domain.composite;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMapping;
|
||||
|
@ -41,6 +40,7 @@ public abstract class AbstractCompositeInitializer extends AbstractFetchParentAc
|
|||
private Object compositeInstance;
|
||||
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public AbstractCompositeInitializer(
|
||||
CompositeResultMappingNode resultDescriptor,
|
||||
FetchParentAccess fetchParentAccess,
|
||||
|
@ -52,7 +52,7 @@ public abstract class AbstractCompositeInitializer extends AbstractFetchParentAc
|
|||
|
||||
final int numOfAttrs = embeddedModelPartDescriptor.getEmbeddableTypeDescriptor().getNumberOfAttributeMappings();
|
||||
this.resolvedValues = new Object[ numOfAttrs ];
|
||||
this.assemblerMap = CollectionHelper.mapOfSize( numOfAttrs );
|
||||
this.assemblerMap = new IdentityHashMap<>( numOfAttrs );
|
||||
|
||||
this.embeddedModelPartDescriptor.getEmbeddableTypeDescriptor().visitStateArrayContributors(
|
||||
stateArrayContributor -> {
|
||||
|
@ -73,6 +73,7 @@ public abstract class AbstractCompositeInitializer extends AbstractFetchParentAc
|
|||
return embeddedModelPartDescriptor;
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public FetchParentAccess getFetchParentAccess() {
|
||||
return fetchParentAccess;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.sql.results.internal.domain.entity;
|
|||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
@ -75,7 +76,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
private final DomainResultAssembler discriminatorAssembler;
|
||||
private final DomainResultAssembler versionAssembler;
|
||||
|
||||
private final Map<StateArrayContributorMapping, DomainResultAssembler> assemblerMap = new HashMap<>();
|
||||
private final Map<StateArrayContributorMapping, DomainResultAssembler> assemblerMap;
|
||||
|
||||
// per-row state
|
||||
private EntityPersister concreteDescriptor;
|
||||
|
@ -132,6 +133,8 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
|||
this.versionAssembler = null;
|
||||
}
|
||||
|
||||
assemblerMap = new IdentityHashMap<>( entityDescriptor.getNumberOfAttributeMappings() );
|
||||
|
||||
entityDescriptor.visitStateArrayContributors(
|
||||
attributeMapping -> {
|
||||
// todo (6.0) : somehow we need to track whether all state is loaded/resolved
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.test.query.hql;
|
||||
|
||||
import org.hibernate.orm.test.metamodel.mapping.SmokeTests;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@DomainModel( annotatedClasses = SmokeTests.SimpleEntity.class )
|
||||
@ServiceRegistry
|
||||
@SessionFactory( exportSchema = true )
|
||||
public class QueryPlanCachingTest {
|
||||
@Test
|
||||
public void testHqlTranslationCaching(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createQuery( "select e from SimpleEntity e" ).list();
|
||||
session.createQuery( "select e from SimpleEntity e" ).list();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -9,11 +9,10 @@ package org.hibernate.orm.test.sql.exec;
|
|||
import java.sql.Statement;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.Component;
|
||||
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.Gender;
|
||||
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.SimpleEntity;
|
||||
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.OtherEntity;
|
||||
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.SimpleEntity;
|
||||
import org.hibernate.query.Query;
|
||||
import org.hibernate.query.spi.QueryImplementor;
|
||||
|
||||
|
@ -37,7 +36,7 @@ import static org.hibernate.orm.test.metamodel.mapping.SmokeTests.Gender.MALE;
|
|||
* @author Andrea Boriero
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@SuppressWarnings({"WeakerAccess", "DefaultAnnotationParam"})
|
||||
@DomainModel(
|
||||
annotatedClasses = {SimpleEntity.class, OtherEntity.class},
|
||||
extraQueryImportClasses = {
|
||||
|
@ -47,15 +46,8 @@ import static org.hibernate.orm.test.metamodel.mapping.SmokeTests.Gender.MALE;
|
|||
SmokeTests.BasicSetterBasedDto.class
|
||||
}
|
||||
)
|
||||
@ServiceRegistry(
|
||||
settings = {
|
||||
@ServiceRegistry.Setting(
|
||||
name = AvailableSettings.HBM2DDL_AUTO,
|
||||
value = "create-drop"
|
||||
)
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
@ServiceRegistry
|
||||
@SessionFactory( exportSchema = true )
|
||||
public class SmokeTests {
|
||||
|
||||
@BeforeEach
|
||||
|
|
|
@ -24,4 +24,6 @@ hibernate.cache.region.factory_class org.hibernate.testing.cache.CachingRegionFa
|
|||
javax.persistence.validation.mode=NONE
|
||||
hibernate.service.allow_crawling=false
|
||||
hibernate.session.events.log=true
|
||||
hibernate.hql.bulk_id_strategy.global_temporary.drop_tables=true
|
||||
hibernate.hql.bulk_id_strategy.global_temporary.drop_tables=true
|
||||
|
||||
hibernate.bytecode.use_reflection_optimizer=true
|
Loading…
Reference in New Issue