HHH-8977 Guess reasonable size for ArrayList and IdentitySet for Query perform

This commit is contained in:
Sanne Grinovero 2014-02-18 00:54:59 +00:00 committed by Brett Meyer
parent d3d2c4c549
commit 85e158d161
1 changed files with 31 additions and 4 deletions

View File

@ -205,8 +205,9 @@ public class HQLQueryPlan implements Serializable {
queryParameters.traceParameters( session.getFactory() ); queryParameters.traceParameters( session.getFactory() );
} }
final boolean hasLimit = queryParameters.getRowSelection() != null final RowSelection rowSelection = queryParameters.getRowSelection();
&& queryParameters.getRowSelection().definesLimits(); final boolean hasLimit = rowSelection != null
&& rowSelection.definesLimits();
final boolean needsLimit = hasLimit && translators.length > 1; final boolean needsLimit = hasLimit && translators.length > 1;
final QueryParameters queryParametersToUse; final QueryParameters queryParametersToUse;
@ -221,8 +222,9 @@ public class HQLQueryPlan implements Serializable {
queryParametersToUse = queryParameters; queryParametersToUse = queryParameters;
} }
final List combinedResults = new ArrayList(); final int guessedResultSize = guessResultSize( rowSelection );
final 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 ) {
@ -257,6 +259,31 @@ 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. * Coordinates the efforts to perform an iterate across all the included query translators.
* *