PlatformDependent ASCII hash code broken on big endian machines
Motivation: PlatformDependent has a hash code algorithm which utilizes UNSAFE for performance reasons. This hash code algorithm must also be consistent with CharSequence objects that represent a collection of ASCII characters. In order to make the UNSAFE versions and CharSequence versions the endianness should be taken into account. However the big endian code was not correct in a few places. Modifications: - Correct bugs in PlatformDependent class related to big endian ASCII hash code computation Result: Fixes https://github.com/netty/netty/issues/5925
This commit is contained in:
parent
cfa5b85075
commit
9cfa467554
@ -439,7 +439,7 @@ public final class PlatformDependent {
|
|||||||
((long) bytes[offset + 4] & 0xff) << 32 |
|
((long) bytes[offset + 4] & 0xff) << 32 |
|
||||||
((long) bytes[offset + 5] & 0xff) << 40 |
|
((long) bytes[offset + 5] & 0xff) << 40 |
|
||||||
((long) bytes[offset + 6] & 0xff) << 48 |
|
((long) bytes[offset + 6] & 0xff) << 48 |
|
||||||
((long) bytes[offset + 7] & 0xff) << 56;
|
(long) bytes[offset + 7] << 56;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getIntSafe(byte[] bytes, int offset) {
|
private static int getIntSafe(byte[] bytes, int offset) {
|
||||||
@ -466,8 +466,13 @@ public final class PlatformDependent {
|
|||||||
* Identical to {@link PlatformDependent0#hashCodeAsciiCompute(long, int)} but for {@link CharSequence}.
|
* Identical to {@link PlatformDependent0#hashCodeAsciiCompute(long, int)} but for {@link CharSequence}.
|
||||||
*/
|
*/
|
||||||
private static int hashCodeAsciiCompute(CharSequence value, int offset, int hash) {
|
private static int hashCodeAsciiCompute(CharSequence value, int offset, int hash) {
|
||||||
// masking with 0x1f reduces the number of overall bits that impact the hash code but makes the hash
|
if (BIG_ENDIAN_NATIVE_ORDER) {
|
||||||
// code the same regardless of character case (upper case or lower case hash is the same).
|
return hash * HASH_CODE_C1 +
|
||||||
|
// Low order int
|
||||||
|
hashCodeAsciiSanitizeInt(value, offset + 4) * HASH_CODE_C2 +
|
||||||
|
// High order int
|
||||||
|
hashCodeAsciiSanitizeInt(value, offset);
|
||||||
|
}
|
||||||
return hash * HASH_CODE_C1 +
|
return hash * HASH_CODE_C1 +
|
||||||
// Low order int
|
// Low order int
|
||||||
hashCodeAsciiSanitizeInt(value, offset) * HASH_CODE_C2 +
|
hashCodeAsciiSanitizeInt(value, offset) * HASH_CODE_C2 +
|
||||||
@ -481,7 +486,7 @@ public final class PlatformDependent {
|
|||||||
private static int hashCodeAsciiSanitizeInt(CharSequence value, int offset) {
|
private static int hashCodeAsciiSanitizeInt(CharSequence value, int offset) {
|
||||||
if (BIG_ENDIAN_NATIVE_ORDER) {
|
if (BIG_ENDIAN_NATIVE_ORDER) {
|
||||||
// mimic a unsafe.getInt call on a big endian machine
|
// mimic a unsafe.getInt call on a big endian machine
|
||||||
return (value.charAt(offset) & 0x1f) |
|
return (value.charAt(offset + 3) & 0x1f) |
|
||||||
(value.charAt(offset + 2) & 0x1f) << 8 |
|
(value.charAt(offset + 2) & 0x1f) << 8 |
|
||||||
(value.charAt(offset + 1) & 0x1f) << 16 |
|
(value.charAt(offset + 1) & 0x1f) << 16 |
|
||||||
(value.charAt(offset) & 0x1f) << 24;
|
(value.charAt(offset) & 0x1f) << 24;
|
||||||
|
Loading…
Reference in New Issue
Block a user