-
Notifications
You must be signed in to change notification settings - Fork 139
Expand file tree
/
Copy pathModernCompactStringHash.java
More file actions
69 lines (61 loc) · 2.63 KB
/
ModernCompactStringHash.java
File metadata and controls
69 lines (61 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/*
* Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0
*/
package net.openhft.hashing;
import java.lang.reflect.Field;
import javax.annotation.ParametersAreNonnullByDefault;
import static net.openhft.hashing.Util.*;
@ParametersAreNonnullByDefault
enum ModernCompactStringHash implements StringHash {
INSTANCE;
private static final long valueOffset;
private static final boolean enableCompactStrings;
private static final Access<byte[]> compactLatin1Access
= CompactLatin1CharSequenceAccess.INSTANCE;
static {
try {
final Field valueField = String.class.getDeclaredField("value");
valueOffset = UnsafeAccess.UNSAFE.objectFieldOffset(valueField);
final byte[] value = (byte[]) UnsafeAccess.UNSAFE.getObject("A", valueOffset);
enableCompactStrings = (1 == value.length);
} catch (final NoSuchFieldException e) {
throw new AssertionError(e);
}
}
@Override
public long longHash(final String s, final LongHashFunction hashFunction,
final int off, final int len) {
final int sl = s.length();
if (len <= 0 || sl <= 0) {
checkArrayOffs(sl, off, len); // check as chars
return hashFunction.hashVoid();
} else {
final byte[] value = (byte[]) UnsafeAccess.UNSAFE.getObject(s, valueOffset);
if (enableCompactStrings && sl == value.length) {
checkArrayOffs(sl, off, len); // check as chars
// 'off' and 'len' are passed as bytes
return hashFunction.hash(value, compactLatin1Access, (long)off*2L, (long)len*2L);
} else {
return hashFunction.hashBytes(value, off*2, len*2); // hash as bytes
}
}
}
@Override
public void hash(final String s, final LongTupleHashFunction hashFunction,
final int off, final int len, final long[] result) {
final int sl = s.length();
if (len <= 0 || sl <= 0) {
checkArrayOffs(sl, off, len); // check as chars
hashFunction.hashVoid(result);
} else {
final byte[] value = (byte[]) UnsafeAccess.UNSAFE.getObject(s, valueOffset);
if (enableCompactStrings && sl == value.length) {
checkArrayOffs(sl, off, len); // check as chars
// 'off' and 'len' are passed as bytes
hashFunction.hash(value, compactLatin1Access, (long)off*2L, (long)len*2L, result);
} else {
hashFunction.hashBytes(value, off*2, len*2, result); // hash as bytes
}
}
}
}