HHH-12131 Avoid allocating unneeded byte array when parsing or
transforming UUID.
This commit is contained in:
parent
4efac1369a
commit
5a5bd47493
|
@ -68,16 +68,29 @@ public final class BytesHelper {
|
|||
*/
|
||||
public static byte[] fromLong(long longValue) {
|
||||
byte[] bytes = new byte[8];
|
||||
bytes[0] = (byte) ( longValue >> 56 );
|
||||
bytes[1] = (byte) ( ( longValue << 8 ) >> 56 );
|
||||
bytes[2] = (byte) ( ( longValue << 16 ) >> 56 );
|
||||
bytes[3] = (byte) ( ( longValue << 24 ) >> 56 );
|
||||
bytes[4] = (byte) ( ( longValue << 32 ) >> 56 );
|
||||
bytes[5] = (byte) ( ( longValue << 40 ) >> 56 );
|
||||
bytes[6] = (byte) ( ( longValue << 48 ) >> 56 );
|
||||
bytes[7] = (byte) ( ( longValue << 56 ) >> 56 );
|
||||
fromLong(longValue, bytes, 0);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret a long as its binary form
|
||||
*
|
||||
* @param longValue The long to interpret to binary
|
||||
* @param dest the destination array.
|
||||
* @param destPos starting position in the destination array.
|
||||
* @return The binary
|
||||
*/
|
||||
public static void fromLong(long longValue, byte[] dest, int destPos) {
|
||||
|
||||
dest[destPos] = (byte) ( longValue >> 56 );
|
||||
dest[destPos + 1] = (byte) ( ( longValue << 8 ) >> 56 );
|
||||
dest[destPos + 2] = (byte) ( ( longValue << 16 ) >> 56 );
|
||||
dest[destPos + 3] = (byte) ( ( longValue << 24 ) >> 56 );
|
||||
dest[destPos + 4] = (byte) ( ( longValue << 32 ) >> 56 );
|
||||
dest[destPos + 5] = (byte) ( ( longValue << 40 ) >> 56 );
|
||||
dest[destPos + 6] = (byte) ( ( longValue << 48 ) >> 56 );
|
||||
dest[destPos + 7] = (byte) ( ( longValue << 56 ) >> 56 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret the binary representation of a long.
|
||||
|
@ -87,14 +100,27 @@ public final class BytesHelper {
|
|||
* @return The long
|
||||
*/
|
||||
public static long asLong(byte[] bytes) {
|
||||
return asLong(bytes, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret the binary representation of a long.
|
||||
*
|
||||
* @param bytes The bytes to interpret.
|
||||
* @param srcPos starting position in the source array.
|
||||
*
|
||||
* @return The long
|
||||
*/
|
||||
public static long asLong(byte[] bytes, int srcPos) {
|
||||
if ( bytes == null ) {
|
||||
return 0;
|
||||
}
|
||||
if ( bytes.length != 8 ) {
|
||||
final int size = srcPos + 8;
|
||||
if ( bytes.length < size ) {
|
||||
throw new IllegalArgumentException( "Expecting 8 byte values to construct a long" );
|
||||
}
|
||||
long value = 0;
|
||||
for (int i=0; i<8; i++) {
|
||||
for (int i=srcPos; i<size; i++) {
|
||||
value = (value << 8) | (bytes[i] & 0xff);
|
||||
}
|
||||
return value;
|
||||
|
|
|
@ -99,17 +99,14 @@ public class UUIDTypeDescriptor extends AbstractTypeDescriptor<UUID> {
|
|||
|
||||
public byte[] transform(UUID uuid) {
|
||||
byte[] bytes = new byte[16];
|
||||
System.arraycopy( BytesHelper.fromLong( uuid.getMostSignificantBits() ), 0, bytes, 0, 8 );
|
||||
System.arraycopy( BytesHelper.fromLong( uuid.getLeastSignificantBits() ), 0, bytes, 8, 8 );
|
||||
BytesHelper.fromLong( uuid.getMostSignificantBits(), bytes, 0);
|
||||
BytesHelper.fromLong( uuid.getLeastSignificantBits(), bytes, 8 );
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public UUID parse(Object value) {
|
||||
byte[] msb = new byte[8];
|
||||
byte[] lsb = new byte[8];
|
||||
System.arraycopy( value, 0, msb, 0, 8 );
|
||||
System.arraycopy( value, 8, lsb, 0, 8 );
|
||||
return new UUID( BytesHelper.asLong( msb ), BytesHelper.asLong( lsb ) );
|
||||
byte[] bytea = (byte[]) value;
|
||||
return new UUID( BytesHelper.asLong( bytea, 0 ), BytesHelper.asLong( bytea, 8 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.test.util;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.hibernate.internal.util.BytesHelper;
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Benoit W
|
||||
*/
|
||||
public class BytesHelperTest extends BaseUnitTestCase {
|
||||
|
||||
@Test
|
||||
public void testAsLongNullArray() {
|
||||
assertEquals(0, BytesHelper.asLong(null, 0));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testAsLongArrayTooSmall() {
|
||||
byte[] src = new byte[16];
|
||||
assertEquals(0, BytesHelper.asLong(src, 9));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsLong() {
|
||||
byte[] src = new byte[] {-92, -120, -59, -64, 97, 55, -41, -55, 64, -43, 20, 109, -7, -95, 77, -115};
|
||||
assertEquals(-6590800624601278519L, BytesHelper.asLong(src, 0));
|
||||
assertEquals(4671662651038846349L, BytesHelper.asLong(src, 8));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testfromLong() {
|
||||
byte[] expected = new byte[] {-92, -120, -59, -64, 97, 55, -41, -55, 64, -43, 20, 109, -7, -95, 77, -115};
|
||||
byte[] dest = new byte[16];
|
||||
BytesHelper.fromLong(-6590800624601278519L, dest, 0);
|
||||
BytesHelper.fromLong(4671662651038846349L, dest, 8);
|
||||
assertArrayEquals(expected, dest);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue