Skip to content

Commit 8f58c1f

Browse files
committed
Polish.
Pull request: spring-projects#2525
1 parent 1d293d8 commit 8f58c1f

File tree

5 files changed

+306
-163
lines changed

5 files changed

+306
-163
lines changed

src/main/java/org/springframework/data/redis/connection/ClusterSlotHashUtil.java

+54-35
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,18 @@
2323
import org.springframework.util.Assert;
2424

2525
/**
26+
* Utility class encapsulating functionality commonly used for cluster slot hashing.
27+
*
2628
* @author Christoph Strobl
29+
* @author John Blum
2730
* @since 1.7
2831
*/
29-
public final class ClusterSlotHashUtil {
32+
public abstract class ClusterSlotHashUtil {
3033

3134
public static final int SLOT_COUNT = 16384;
3235

33-
private static final byte SUBKEY_START = '{';
34-
private static final byte SUBKEY_END = '}';
36+
protected static final byte SUBKEY_START = '{';
37+
protected static final byte SUBKEY_END = '}';
3538

3639
private static final int[] LOOKUP_TABLE = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108,
3740
0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7,
@@ -53,93 +56,109 @@ public final class ClusterSlotHashUtil {
5356
0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9,
5457
0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 };
5558

56-
private ClusterSlotHashUtil() {
57-
58-
}
59-
6059
/**
61-
* @param keys must not be {@literal null}.
62-
* @return
63-
* @since 2.0
60+
* Determines whether all keys will hash to the same slot.
61+
*
62+
* @param keys array of keys to evaluate3; must not be {@literal null}.
63+
* @return a boolean value indicating whether all keys will hash to the same slot.
64+
* @throws IllegalArgumentException if the byte array of keys is {@literal null}.
6465
*/
65-
public static boolean isSameSlotForAllKeys(Collection<ByteBuffer> keys) {
66+
public static boolean isSameSlotForAllKeys(byte[]... keys) {
6667

6768
Assert.notNull(keys, "Keys must not be null");
6869

69-
if (keys.size() <= 1) {
70+
if (keys.length <= 1) {
7071
return true;
7172
}
7273

73-
return isSameSlotForAllKeys((byte[][]) keys.stream() //
74-
.map(ByteBuffer::duplicate) //
75-
.map(ByteUtils::getBytes) //
76-
.toArray(byte[][]::new));
74+
int slot = calculateSlot(keys[0]);
75+
76+
for (int i = 1; i < keys.length; i++) {
77+
if (slot != calculateSlot(keys[i])) {
78+
return false;
79+
}
80+
}
81+
82+
return true;
7783
}
7884

7985
/**
80-
* @param keys must not be {@literal null}.
81-
* @return
86+
* Determines whether all keys will hash to the same slot.
87+
*
88+
* @param keys array of {@link ByteBuffer} objects containing the keys to evaluate; must not be {@literal null}.
89+
* @return a boolean value indicating whether all keys will hash to the same slot.
90+
* @throws IllegalArgumentException if the array of keys is {@literal null}.
91+
* @see #isSameSlotForAllKeys(Collection)
8292
* @since 2.0
8393
*/
8494
public static boolean isSameSlotForAllKeys(ByteBuffer... keys) {
8595

8696
Assert.notNull(keys, "Keys must not be null");
97+
8798
return isSameSlotForAllKeys(Arrays.asList(keys));
8899
}
89100

90101
/**
91-
* @param keys must not be {@literal null}.
92-
* @return
102+
* Determines whether all keys will hash to the same slot.
103+
*
104+
* @param keys {@link Collection} of {@link ByteBuffer} objects containing the keys to evaluate;
105+
* must not be {@literal null}.
106+
* @return a boolean value indicating whether all keys will hash to the same slot.
107+
* @throws IllegalArgumentException if the {@link Collection} of keys is {@literal null}.
108+
* @since 2.0
93109
*/
94-
public static boolean isSameSlotForAllKeys(byte[]... keys) {
110+
public static boolean isSameSlotForAllKeys(Collection<ByteBuffer> keys) {
95111

96112
Assert.notNull(keys, "Keys must not be null");
97113

98-
if (keys.length <= 1) {
114+
if (keys.size() <= 1) {
99115
return true;
100116
}
101117

102-
int slot = calculateSlot(keys[0]);
103-
for (int i = 1; i < keys.length; i++) {
104-
if (slot != calculateSlot(keys[i])) {
105-
return false;
106-
}
107-
}
108-
return true;
118+
return isSameSlotForAllKeys(keys.stream()
119+
.map(ByteBuffer::duplicate)
120+
.map(ByteUtils::getBytes)
121+
.toArray(byte[][]::new));
109122
}
110123

111124
/**
112125
* Calculate the slot from the given key.
113126
*
114-
* @param key must not be {@literal null} or empty.
115-
* @return
127+
* @param key {@link String} containing the Redis key to evaluate; must not be {@literal null} or {@literal empty}.
128+
* @return the computed slot based on the given key.
129+
* @throws IllegalArgumentException if the given {@link String key} is {@literal null} or {@literal empty}.
130+
* @see #calculateSlot(byte[])
116131
*/
117132
public static int calculateSlot(String key) {
118133

119134
Assert.hasText(key, "Key must not be null or empty");
135+
120136
return calculateSlot(key.getBytes());
121137
}
122138

123139
/**
124140
* Calculate the slot from the given key.
125141
*
126-
* @param key must not be {@literal null}.
127-
* @return
142+
* @param key array of bytes containing the Redis key to evaluate; must not be {@literal null}.
143+
* @return the computed slot based on the given key.
128144
*/
129145
public static int calculateSlot(byte[] key) {
130146

131147
Assert.notNull(key, "Key must not be null");
132148

133149
byte[] finalKey = key;
134150
int start = indexOf(key, SUBKEY_START);
151+
135152
if (start != -1) {
153+
136154
int end = indexOf(key, start + 1, SUBKEY_END);
137-
if (end != -1 && end != start + 1) {
138155

156+
if (end != -1 && end != start + 1) {
139157
finalKey = new byte[end - (start + 1)];
140158
System.arraycopy(key, start + 1, finalKey, 0, finalKey.length);
141159
}
142160
}
161+
143162
return crc16(finalKey) % SLOT_COUNT;
144163
}
145164

@@ -150,7 +169,6 @@ private static int indexOf(byte[] haystack, byte needle) {
150169
private static int indexOf(byte[] haystack, int start, byte needle) {
151170

152171
for (int i = start; i < haystack.length; i++) {
153-
154172
if (haystack[i] == needle) {
155173
return i;
156174
}
@@ -166,6 +184,7 @@ private static int crc16(byte[] bytes) {
166184
for (byte b : bytes) {
167185
crc = ((crc << 8) ^ LOOKUP_TABLE[((crc >>> 8) ^ (b & 0xFF)) & 0xFF]);
168186
}
187+
169188
return crc & 0xFFFF;
170189
}
171190
}

0 commit comments

Comments
 (0)