mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-25 21:04:51 +00:00
HHH-16884 Improve efficiency of UpdateCoordinatorStandard in tracking tables to be updated
This commit is contained in:
parent
9056695f70
commit
db0427173b
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* 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.persister.entity.mutation;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
import org.hibernate.sql.model.MutationTarget;
|
||||||
|
import org.hibernate.sql.model.TableMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Set of TableMapping(s); table mappings are
|
||||||
|
* identified by an ordered unique id: the order in which
|
||||||
|
* they are updated within the scope of a particular persister.
|
||||||
|
* This makes it possible to store a set of them as a bitset,
|
||||||
|
* which is typically more efficient than using a {@link java.util.Set}.
|
||||||
|
* These table ids relate to the use in method {@link MutationTarget#forEachMutableTable}
|
||||||
|
* and {@link MutationTarget#forEachMutableTableReverse}.
|
||||||
|
* <p>N.B. Make sure to not store TableMappings from different
|
||||||
|
* persisters, as their unique identifiers will overlap:
|
||||||
|
* we'll only verify a mismatch if assertions are enabled.</p>
|
||||||
|
*/
|
||||||
|
public final class TableSet {
|
||||||
|
|
||||||
|
private BitSet bits;
|
||||||
|
private Object[] checks; //Meant for assertions only
|
||||||
|
|
||||||
|
public void add(final TableMapping tableMapping) {
|
||||||
|
if ( bits == null ) {
|
||||||
|
bits = new BitSet();
|
||||||
|
}
|
||||||
|
assert addForChecks( tableMapping );
|
||||||
|
bits.set( tableMapping.getRelativePosition() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return bits == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(final TableMapping tableMapping) {
|
||||||
|
assert matchRead( tableMapping );
|
||||||
|
return bits != null && bits.get( tableMapping.getRelativePosition() );
|
||||||
|
}
|
||||||
|
|
||||||
|
//Meant for assertions only
|
||||||
|
private boolean matchRead(final TableMapping tableMapping) {
|
||||||
|
if ( bits != null ) {
|
||||||
|
final int index = tableMapping.getRelativePosition();
|
||||||
|
if ( bits.get( index ) ) {
|
||||||
|
return checks[index] == tableMapping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true; //to make the assertion happy
|
||||||
|
}
|
||||||
|
|
||||||
|
//Meant for assertions only
|
||||||
|
private boolean addForChecks(final TableMapping tableMapping) {
|
||||||
|
final int position = tableMapping.getRelativePosition();
|
||||||
|
ensureCapacity( position );
|
||||||
|
if ( checks[position] != null ) {
|
||||||
|
//pre-existing in the set: verify it's the same one.
|
||||||
|
if ( checks[position] != tableMapping ) {
|
||||||
|
return false;//fail the assertion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checks[position] = tableMapping;
|
||||||
|
return true; //to make the assertion happy
|
||||||
|
}
|
||||||
|
|
||||||
|
//Meant for assertions only
|
||||||
|
private void ensureCapacity(final int position) {
|
||||||
|
final int increments = 3; //Needs to be at least 1.
|
||||||
|
if ( checks == null ) {
|
||||||
|
checks = new Object[position + increments];
|
||||||
|
}
|
||||||
|
else if ( checks.length <= position ) {
|
||||||
|
checks = Arrays.copyOf( checks, position + increments );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1274,10 +1274,10 @@ protected class UpdateValuesAnalysisImpl implements UpdateValuesAnalysis {
|
|||||||
private final int[] dirtyAttributeIndexes;
|
private final int[] dirtyAttributeIndexes;
|
||||||
private final InclusionChecker dirtinessChecker;
|
private final InclusionChecker dirtinessChecker;
|
||||||
|
|
||||||
private final Set<EntityTableMapping> tablesNeedingUpdate = new HashSet<>();
|
private final TableSet tablesNeedingUpdate = new TableSet();
|
||||||
private final Set<EntityTableMapping> tablesNeedingDynamicUpdate = new HashSet<>();
|
private final TableSet tablesNeedingDynamicUpdate = new TableSet();
|
||||||
private final Set<EntityTableMapping> tablesWithNonNullValues = new HashSet<>();
|
private final TableSet tablesWithNonNullValues = new TableSet();
|
||||||
private final Set<EntityTableMapping> tablesWithPreviousNonNullValues = new HashSet<>();
|
private final TableSet tablesWithPreviousNonNullValues = new TableSet();
|
||||||
|
|
||||||
private final List<AttributeAnalysis> attributeAnalyses = new ArrayList<>();
|
private final List<AttributeAnalysis> attributeAnalyses = new ArrayList<>();
|
||||||
|
|
||||||
@ -1348,17 +1348,17 @@ public Object[] getValues() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<EntityTableMapping> getTablesNeedingUpdate() {
|
public TableSet getTablesNeedingUpdate() {
|
||||||
return tablesNeedingUpdate;
|
return tablesNeedingUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<EntityTableMapping> getTablesWithNonNullValues() {
|
public TableSet getTablesWithNonNullValues() {
|
||||||
return tablesWithNonNullValues;
|
return tablesWithNonNullValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<EntityTableMapping> getTablesWithPreviousNonNullValues() {
|
public TableSet getTablesWithPreviousNonNullValues() {
|
||||||
return tablesWithPreviousNonNullValues;
|
return tablesWithPreviousNonNullValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
package org.hibernate.persister.entity.mutation;
|
package org.hibernate.persister.entity.mutation;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.hibernate.Incubating;
|
import org.hibernate.Incubating;
|
||||||
import org.hibernate.sql.model.TableMapping;
|
import org.hibernate.sql.model.TableMapping;
|
||||||
@ -29,17 +28,17 @@ public interface UpdateValuesAnalysis extends ValuesAnalysis {
|
|||||||
*
|
*
|
||||||
* @apiNote {@linkplain TableMapping#isInverse() Inverse tables} are not included in the result
|
* @apiNote {@linkplain TableMapping#isInverse() Inverse tables} are not included in the result
|
||||||
*/
|
*/
|
||||||
Set<EntityTableMapping> getTablesNeedingUpdate();
|
TableSet getTablesNeedingUpdate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Descriptor of the tables which had any non-null value bindings
|
* Descriptor of the tables which had any non-null value bindings
|
||||||
*/
|
*/
|
||||||
Set<EntityTableMapping> getTablesWithNonNullValues();
|
TableSet getTablesWithNonNullValues();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Descriptor of the tables which had any non-null value bindings
|
* Descriptor of the tables which had any non-null value bindings
|
||||||
*/
|
*/
|
||||||
Set<EntityTableMapping> getTablesWithPreviousNonNullValues();
|
TableSet getTablesWithPreviousNonNullValues();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Descriptors for the analysis of each attribute
|
* Descriptors for the analysis of each attribute
|
||||||
|
Loading…
x
Reference in New Issue
Block a user