HHH-8977 Guess reasonable size for ArrayList and IdentitySet for Query
perform Conflicts: hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java
This commit is contained in:
parent
8e5e8d1b14
commit
ec5987278d
|
@ -32,8 +32,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.QueryException;
|
import org.hibernate.QueryException;
|
||||||
import org.hibernate.ScrollableResults;
|
import org.hibernate.ScrollableResults;
|
||||||
|
@ -53,6 +51,7 @@ import org.hibernate.internal.util.collections.EmptyIterator;
|
||||||
import org.hibernate.internal.util.collections.IdentitySet;
|
import org.hibernate.internal.util.collections.IdentitySet;
|
||||||
import org.hibernate.internal.util.collections.JoinedIterator;
|
import org.hibernate.internal.util.collections.JoinedIterator;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a query execution plan for an HQL query (or filter).
|
* Defines a query execution plan for an HQL query (or filter).
|
||||||
|
@ -172,10 +171,13 @@ public class HQLQueryPlan implements Serializable {
|
||||||
LOG.tracev( "Find: {0}", getSourceQuery() );
|
LOG.tracev( "Find: {0}", getSourceQuery() );
|
||||||
queryParameters.traceParameters( session.getFactory() );
|
queryParameters.traceParameters( session.getFactory() );
|
||||||
}
|
}
|
||||||
boolean hasLimit = queryParameters.getRowSelection() != null &&
|
|
||||||
queryParameters.getRowSelection().definesLimits();
|
final RowSelection rowSelection = queryParameters.getRowSelection();
|
||||||
boolean needsLimit = hasLimit && translators.length > 1;
|
final boolean hasLimit = rowSelection != null
|
||||||
QueryParameters queryParametersToUse;
|
&& rowSelection.definesLimits();
|
||||||
|
final boolean needsLimit = hasLimit && translators.length > 1;
|
||||||
|
|
||||||
|
final QueryParameters queryParametersToUse;
|
||||||
if ( needsLimit ) {
|
if ( needsLimit ) {
|
||||||
LOG.needsLimit();
|
LOG.needsLimit();
|
||||||
RowSelection selection = new RowSelection();
|
RowSelection selection = new RowSelection();
|
||||||
|
@ -187,8 +189,9 @@ public class HQLQueryPlan implements Serializable {
|
||||||
queryParametersToUse = queryParameters;
|
queryParametersToUse = queryParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
List combinedResults = new ArrayList();
|
final int guessedResultSize = guessResultSize( rowSelection );
|
||||||
IdentitySet distinction = new IdentitySet();
|
final List combinedResults = new ArrayList( guessedResultSize );
|
||||||
|
final IdentitySet distinction = new IdentitySet( guessedResultSize );
|
||||||
int includedCount = -1;
|
int includedCount = -1;
|
||||||
translator_loop:
|
translator_loop:
|
||||||
for ( QueryTranslator translator : translators ) {
|
for ( QueryTranslator translator : translators ) {
|
||||||
|
@ -223,6 +226,42 @@ public class HQLQueryPlan implements Serializable {
|
||||||
return combinedResults;
|
return combinedResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we're able to guess a likely size of the results we can optimize allocation
|
||||||
|
* of our datastructures.
|
||||||
|
* Essentially if we detect the user is not using pagination, we attempt to use the FetchSize
|
||||||
|
* as a reasonable hint. If fetch size is not being set either, it is reasonable to expect
|
||||||
|
* that we're going to have a single hit. In such a case it would be tempting to return a constant
|
||||||
|
* of value one, but that's dangerous as it doesn't scale up appropriately for example
|
||||||
|
* with an ArrayList if the guess is wrong.
|
||||||
|
*
|
||||||
|
* @param rowSelection
|
||||||
|
* @return a reasonable size to use for allocation
|
||||||
|
*/
|
||||||
|
private final int guessResultSize(RowSelection rowSelection) {
|
||||||
|
if ( rowSelection != null ) {
|
||||||
|
final int maxReasonableAllocation = rowSelection.getFetchSize() != null ? rowSelection.getFetchSize().intValue() : 100;
|
||||||
|
if ( rowSelection.getMaxRows() != null && rowSelection.getMaxRows().intValue() > 0 ) {
|
||||||
|
return Math.min( maxReasonableAllocation, rowSelection.getMaxRows().intValue() );
|
||||||
|
}
|
||||||
|
else if ( rowSelection.getFetchSize() != null && rowSelection.getFetchSize().intValue() > 0 ) {
|
||||||
|
return rowSelection.getFetchSize().intValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 7;//magic number guessed as a reasonable default.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Coordinates the efforts to perform an iterate across all the included query translators.
|
||||||
|
*
|
||||||
|
* @param queryParameters The query parameters
|
||||||
|
* @param session The session
|
||||||
|
*
|
||||||
|
* @return The query result iterator
|
||||||
|
*
|
||||||
|
* @throws HibernateException Indicates a problem performing the query
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public Iterator performIterate(
|
public Iterator performIterate(
|
||||||
QueryParameters queryParameters,
|
QueryParameters queryParameters,
|
||||||
EventSource session) throws HibernateException {
|
EventSource session) throws HibernateException {
|
||||||
|
|
Loading…
Reference in New Issue