Skip to content

Commit

Permalink
HHH-18410 Make use of getter/setter cache as much as possible
Browse files Browse the repository at this point in the history
  • Loading branch information
beikov committed Aug 6, 2024
1 parent 7ef2691 commit 73af6a0
Show file tree
Hide file tree
Showing 26 changed files with 174 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,14 @@ private void visitEmbeddedAttributeMapping(
if ( attribute.isPluralAttributeMapping() ) {
addCollectionKey(
attribute.asPluralAttributeMapping(),
attribute.getPropertyAccess().getGetter().get( object ),
attribute.getValue( object ),
persistenceContext
);
}
else if ( attribute.isEmbeddedAttributeMapping() ) {
visitEmbeddedAttributeMapping(
attribute.asEmbeddedAttributeMapping(),
attribute.getPropertyAccess().getGetter().get( object ),
attribute.getValue( object ),
persistenceContext
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,16 @@ public static <T> void cascade(
LOG.tracev( "Processing cascade {0} for: {1}", action, persister.getEntityName() );
}
final PersistenceContext persistenceContext = eventSource.getPersistenceContextInternal();
final EntityEntry entry = persistenceContext.getEntry( parent );
if ( entry != null && entry.getLoadedState() == null && entry.getStatus() == Status.MANAGED && persister.getBytecodeEnhancementMetadata()
.isEnhancedForLazyLoading() ) {
return;
final boolean enhancedForLazyLoading = persister.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading();
final EntityEntry entry;
if ( enhancedForLazyLoading ) {
entry = persistenceContext.getEntry( parent );
if ( entry != null && entry.getLoadedState() == null && entry.getStatus() == Status.MANAGED ) {
return;
}
}
else {
entry = null;
}
final Type[] types = persister.getPropertyTypes();
final String[] propertyNames = persister.getPropertyNames();
Expand All @@ -107,6 +113,7 @@ public static <T> void cascade(
if ( style.doCascade( action ) ) {
final Object child;
if ( isUninitializedProperty ) {
assert enhancedForLazyLoading;
// parent is a bytecode enhanced entity.
// Cascade to an uninitialized, lazy value only if
// parent is managed in the PersistenceContext.
Expand Down Expand Up @@ -216,7 +223,7 @@ private static <T> void cascadeProperty(
final String propertyName,
final T anything,
final boolean isCascadeDeleteEnabled) throws HibernateException {

if ( child != null ) {
if ( type.isAssociationType() ) {
final AssociationType associationType = (AssociationType) type;
Expand Down Expand Up @@ -378,7 +385,7 @@ private static <T> void cascadeLogicalOneToOneOrphanRemoval(
* @return True if the attribute represents a logical one to one association
*/
private static boolean isLogicalOneToOne(Type type) {
return type.isEntityType() && ( (EntityType) type ).isLogicalOneToOne();
return type instanceof EntityType && ( (EntityType) type ).isLogicalOneToOne();
}

private static boolean cascadeAssociationNow(final CascadePoint cascadePoint, AssociationType associationType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,7 @@ public static void processReachableCollection(
Object entity,
SessionImplementor session) {
collection.setOwner( entity );
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
final CollectionEntry ce = persistenceContext.getCollectionEntry( collection );
final CollectionEntry ce = session.getPersistenceContextInternal().getCollectionEntry( collection );

if ( ce == null ) {
// refer to comment in StatefulPersistenceContext.addCollection()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1316,7 +1316,7 @@ public int getNumberOfManagedEntities() {
@Override
@Deprecated
public Map<PersistentCollection<?>,CollectionEntry> getCollectionEntries() {
return getOrInitializeCollectionEntries();
return collectionEntries;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,11 @@ EntityHolder claimEntityHolderIfPossible(
JdbcValuesSourceProcessingState processingState,
EntityInitializer initializer);

EntityHolder getEntityHolder(EntityKey key);
@Nullable EntityHolder getEntityHolder(EntityKey key);

boolean containsEntityHolder(EntityKey key);

EntityHolder removeEntityHolder(EntityKey key);
@Nullable EntityHolder removeEntityHolder(EntityKey key);

@Incubating
void postLoad(JdbcValuesSourceProcessingState processingState, Consumer<EntityHolder> loadedConsumer);
Expand Down Expand Up @@ -564,7 +564,7 @@ EntityHolder claimEntityHolderIfPossible(
* Doubly internal
*/
@Internal
Map<PersistentCollection<?>,CollectionEntry> getCollectionEntries();
@Nullable Map<PersistentCollection<?>,CollectionEntry> getCollectionEntries();

/**
* Execute some action on each entry of the collectionEntries map, optionally iterating on a defensive copy.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
import org.hibernate.action.internal.CollectionRemoveAction;
import org.hibernate.action.internal.CollectionUpdateAction;
import org.hibernate.action.internal.QueuedOperationCollectionAction;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.internal.Cascade;
import org.hibernate.engine.internal.CascadePoint;
import org.hibernate.engine.internal.Collections;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.engine.spi.ActionQueue;
import org.hibernate.engine.spi.CascadingAction;
import org.hibernate.engine.spi.CascadingActions;
import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.CollectionKey;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.PersistenceContext;
Expand All @@ -35,6 +37,7 @@
import org.hibernate.event.spi.PersistContext;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.EntityPrinter;
import org.hibernate.internal.util.collections.IdentityMap;
import org.hibernate.persister.entity.EntityPersister;

import org.jboss.logging.Logger;
Expand Down Expand Up @@ -183,7 +186,12 @@ private void prepareCollectionFlushes(PersistenceContext persistenceContext) thr
// and reset reached, doupdate, etc.

LOG.debug( "Dirty checking collections" );
persistenceContext.forEachCollectionEntry( (pc,ce) -> ce.preFlush( pc ), true );
final Map<PersistentCollection<?>, CollectionEntry> collectionEntries = persistenceContext.getCollectionEntries();
if ( collectionEntries != null ) {
for ( Map.Entry<PersistentCollection<?>, CollectionEntry> entry : ( (IdentityMap<PersistentCollection<?>, CollectionEntry>) collectionEntries ).entryArray() ) {
entry.getValue().preFlush( entry.getKey() );
}
}
}

/**
Expand Down Expand Up @@ -262,14 +270,20 @@ private int flushCollections(final EventSource session, final PersistenceContext
throws HibernateException {
LOG.trace( "Processing unreferenced collections" );

final int count = persistenceContext.getCollectionEntriesSize();

persistenceContext.forEachCollectionEntry(
(persistentCollection, collectionEntry) -> {
if ( !collectionEntry.isReached() && !collectionEntry.isIgnore() ) {
Collections.processUnreachableCollection( persistentCollection, session );
}
}, true );
final Map<PersistentCollection<?>, CollectionEntry> collectionEntries = persistenceContext.getCollectionEntries();
final int count;
if ( collectionEntries == null ) {
count = 0;
}
else {
count = collectionEntries.size();
for ( Map.Entry<PersistentCollection<?>, CollectionEntry> me : ( (IdentityMap<PersistentCollection<?>, CollectionEntry>) collectionEntries ).entryArray() ) {
final CollectionEntry ce = me.getValue();
if ( !ce.isReached() && !ce.isIgnore() ) {
Collections.processUnreachableCollection( me.getKey(), session );
}
}
}

// Schedule updates to collections:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,7 @@ protected Object processCollection(Object collection, CollectionType collectionT
.getMappingMetamodel()
.getCollectionDescriptor( collectionType.getRole() );
final CollectionEntry collectionEntry = getSession().getPersistenceContextInternal()
.getCollectionEntries()
.get( coll );
.getCollectionEntry( coll );
if ( !coll.equalsSnapshot( persister ) ) {
collectionEntry.resetStoredSnapshot( coll, coll.getSnapshot( persister ) );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public final class IdentityMap<K,V> implements Map<K,V> {

private final LinkedHashMap<IdentityKey<K>,V> map;

private transient Entry<IdentityKey<K>,V>[] entryArray = null;
private transient Entry<K,V>[] entryArray = null;

/**
* Return a new instance of this class, with iteration
Expand Down Expand Up @@ -151,15 +151,14 @@ public Set<Entry<K,V>> entrySet() {
return set;
}

@SuppressWarnings( {"unchecked"})
public Entry[] entryArray() {
public Entry<K,V>[] entryArray() {
if ( entryArray == null ) {
entryArray = new Entry[ map.size() ];
final Iterator<Entry<IdentityKey<K>, V>> itr = map.entrySet().iterator();
int i = 0;
while ( itr.hasNext() ) {
final Entry<IdentityKey<K>, V> me = itr.next();
entryArray[i++] = new IdentityMapEntry( me.getKey().key, me.getValue() );
entryArray[i++] = new IdentityMapEntry<>( me.getKey().key, me.getValue() );
}
}
return entryArray;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ public <X, Y> int forEachJdbcValue(
else {
for ( int i = 0; i < size; i++ ) {
final AttributeMapping attributeMapping = embeddableTypeDescriptor.getAttributeMapping( i );
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
final Object o = embeddableTypeDescriptor.getValue( value, i );
if ( attributeMapping instanceof ToOneAttributeMapping ) {
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
final ForeignKeyDescriptor fkDescriptor = toOneAttributeMapping.getForeignKeyDescriptor();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ default String getPartName() {
* Convenient access to getting the value for this attribute from the declarer
*/
default Object getValue(Object container) {
return getPropertyAccess().getGetter().get( container );
return getDeclaringType().getValue( container, getStateArrayPosition() );
}

/**
* Convenient access to setting the value for this attribute on the declarer
*/
default void setValue(Object container, Object value) {
getPropertyAccess().getSetter().set( container, value );
getDeclaringType().setValue( container, getStateArrayPosition(), value );
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,8 @@ default void applySqlSelections(
default int compare(Object value1, Object value2) {
final AttributeMappingsList attributeMappings = getAttributeMappings();
for ( int i = 0; i < attributeMappings.size(); i++ ) {
AttributeMapping attributeMapping = attributeMappings.get( i );
final Getter getter = attributeMapping.getPropertyAccess().getGetter();
final int comparison = attributeMapping.compare( getter.get( value1 ), getter.get( value2 ) );
final AttributeMapping attribute = attributeMappings.get( i );
final int comparison = attribute.compare( attribute.getValue( value1 ), attribute.getValue( value2 ) );
if ( comparison != 0 ) {
return comparison;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ default void forEachAttributeMapping(IndexedConsumer<? super AttributeMapping> c
* Extract a specific attribute value from the entity instance, by position
*/
default Object getValue(Object instance, int position) {
return getAttributeMapping( position ).getValue( instance );
return getAttributeMapping( position ).getPropertyAccess().getGetter().get( instance );
}

/**
Expand All @@ -85,7 +85,7 @@ default Object getValue(Object instance, int position) {
* Inject a specific attribute value into the entity instance, by position
*/
default void setValue(Object instance, int position, Object value) {
getAttributeMapping( position ).setValue( instance, value );
getAttributeMapping( position ).getPropertyAccess().getSetter().set( instance, value );
}

default boolean anyRequiresAggregateColumnWriter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
import org.hibernate.property.access.spi.Getter;
import org.hibernate.property.access.spi.PropertyAccess;
import org.hibernate.property.access.spi.Setter;
import org.hibernate.sql.ast.tree.from.TableGroupProducer;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.type.AnyType;
Expand All @@ -70,6 +71,8 @@
public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType {
final protected MutableAttributeMappingList attributeMappings;
protected SelectableMappings selectableMappings;
protected Getter[] getterCache;
protected Setter[] setterCache;

public AbstractEmbeddableMapping(MutableAttributeMappingList attributeMappings) {
this.attributeMappings = attributeMappings;
Expand All @@ -80,6 +83,16 @@ public JavaType<?> getMappedJavaType() {
return getRepresentationStrategy().getMappedJavaType();
}

@Override
public Object getValue(Object instance, int position) {
return getterCache[position].get( instance );
}

@Override
public void setValue(Object instance, int position, Object value) {
setterCache[position].set( instance, value );
}

@Override
public Object[] getValues(Object compositeInstance) {
if ( compositeInstance == PropertyAccessStrategyBackRefImpl.UNKNOWN ) {
Expand All @@ -93,10 +106,7 @@ public Object[] getValues(Object compositeInstance) {

final Object[] results = new Object[getNumberOfAttributeMappings()];
for ( int i = 0; i < results.length; i++ ) {
final Getter getter = getAttributeMapping( i ).getAttributeMetadata()
.getPropertyAccess()
.getGetter();
results[i] = getter.get( compositeInstance );
results[i] = getValue( compositeInstance, i );
}
return results;
}
Expand All @@ -109,7 +119,7 @@ public void setValues(Object component, Object[] values) {
}
else {
for ( int i = 0; i < values.length; i++ ) {
getAttributeMapping( i ).getPropertyAccess().getSetter().set( component, values[i] );
setValue( component, i,values[i] );
}
}
}
Expand Down Expand Up @@ -215,6 +225,7 @@ else if ( attributeMapping instanceof EmbeddableValuedModelPart ) {
}
mappings.add( attributeMapping );
}
buildGetterSetterCache();
return true;
}

Expand Down Expand Up @@ -686,7 +697,7 @@ public <X, Y> int forEachJdbcValue(
if ( attributeMapping instanceof PluralAttributeMapping ) {
continue;
}
final Object o = attributeMapping.getPropertyAccess().getGetter().get( value );
final Object o = getValue( value, i );
span += attributeMapping.forEachJdbcValue( o, span + offset, x, y, valuesConsumer, session );
}
}
Expand Down Expand Up @@ -722,10 +733,24 @@ protected boolean initColumnMappings() {
);

this.selectableMappings = new SelectableMappingsImpl( selectableMappings.toArray( new SelectableMapping[0] ) );
buildGetterSetterCache();

return true;
}

protected void buildGetterSetterCache() {
final int propertySpan = attributeMappings.size();
final Getter[] getterCache = new Getter[propertySpan];
final Setter[] setterCache = new Setter[propertySpan];
for ( int i = 0; i < propertySpan; i++ ) {
final PropertyAccess propertyAccess = attributeMappings.get( i ).getPropertyAccess();
getterCache[i] = propertyAccess.getGetter();
setterCache[i] = propertyAccess.getSetter();
}
this.getterCache = getterCache;
this.setterCache = setterCache;
}

private static MutabilityPlan<?> getMutabilityPlan(boolean updateable) {
if ( updateable ) {
return new MutabilityPlan<>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
import org.hibernate.metamodel.mapping.SelectableConsumer;
import org.hibernate.metamodel.mapping.SelectableMapping;
import org.hibernate.metamodel.mapping.SelectableMappings;
Expand Down Expand Up @@ -658,7 +659,7 @@ public <X, Y> int breakDownJdbcValues(
if ( !attributeMapping.isPluralAttributeMapping() ) {
final Object attributeValue = domainValue == null
? null
: attributeMapping.getPropertyAccess().getGetter().get( domainValue );
: getValue( domainValue, i );
span += attributeMapping.breakDownJdbcValues(
attributeValue,
offset + span,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ public EmbeddedAttributeMapping(
MappingModelCreationProcess creationProcess) {
super(
inverseModelPart.getFetchableName(),
-1,
inverseModelPart.asAttributeMapping() != null
? inverseModelPart.asAttributeMapping().getStateArrayPosition()
: -1,
inverseModelPart.getFetchableKey(),
inverseModelPart.asAttributeMapping() != null
? inverseModelPart.asAttributeMapping().getAttributeMetadata()
Expand Down
Loading

0 comments on commit 73af6a0

Please sign in to comment.