HHH-13512 Avoid allocating an array in org.hibernate.internal.util.StringHelper#unquote(String[], Dialect) if there are no changes to be applied

This commit is contained in:
Sanne Grinovero 2019-08-01 12:23:05 +01:00
parent c35bce15f9
commit 7f6bf82fed
2 changed files with 51 additions and 5 deletions

View File

@ -739,15 +739,32 @@ public final class StringHelper {
*
* @return The unquoted versions.
*/
public static String[] unquote(String[] names, Dialect dialect) {
public static String[] unquote(final String[] names, final Dialect dialect) {
if ( names == null ) {
return null;
}
String[] unquoted = new String[names.length];
for ( int i = 0; i < names.length; i++ ) {
unquoted[i] = unquote( names[i], dialect );
int failedIndex = -1;
final int length = names.length;
for ( int i = 0; i < length; i++ ) {
if ( isQuoted( names[i], dialect ) ) {
failedIndex = i;
break;
}
}
if ( failedIndex == -1 ) {
//In this case all strings are already unquoted, so return the same array as the input:
//this is a good optimisation to skip an array copy as typically either all names are consistently quoted, or none are;
//yet for safety we need to deal with mixed scenarios as well.
return names;
}
else {
String[] unquoted = new String[length];
System.arraycopy( names, 0, unquoted, 0, failedIndex );
for ( int i = failedIndex; i < length; i++ ) {
unquoted[i] = unquote( names[i], dialect );
}
return unquoted;
}
return unquoted;
}

View File

@ -6,18 +6,24 @@
*/
package org.hibernate.test.util;
import java.util.Arrays;
import org.junit.Assert;
import org.junit.Test;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* @author Steve Ebersole
*/
public class StringHelperTest extends BaseUnitTestCase {
private static final String BASE_PACKAGE = "org.hibernate";
private static final String STRING_HELPER_FQN = "org.hibernate.internal.util.StringHelper";
private static final String STRING_HELPER_NAME = StringHelper.unqualify( STRING_HELPER_FQN );
@ -54,4 +60,27 @@ public class StringHelperTest extends BaseUnitTestCase {
assertEquals( StringHelper.indexOfIdentifierWord( "no identifier here", "?1" ), -1 );
assertEquals( StringHelper.indexOfIdentifierWord( "some text ?", "?" ), 10 );
}
private static H2Dialect DIALECT = new H2Dialect();
@Test
public void testArrayUnquoting() {
assertNull( StringHelper.unquote( (String[]) null, DIALECT ) );
//This to verify that the string array isn't being copied unnecessarily:
unchanged( new String [0] );
unchanged( new String[] { "a" } );
unchanged( new String[] { "a", "b" } );
helperEquals( new String[] { "a", "b", "c" }, new String[] { "a", "b", "`c`" } );
helperEquals( new String[] { "a", "b", "c" }, new String[] { "a", "\"b\"", "c" } );
}
private static void unchanged(String[] input) {
final String[] output = StringHelper.unquote( input, DIALECT );
assertTrue( input == output );
}
private static void helperEquals(String[] expectation, String[] input) {
final String[] output = StringHelper.unquote( input, DIALECT );
assertTrue( Arrays.equals( expectation, output ) );
}
}