Skip to content

Commit 29a1810

Browse files
committed
Use BitSet instead of LinkedHashSet to improve the performance of SlotRange construction
1 parent 7e1746c commit 29a1810

File tree

3 files changed

+42
-15
lines changed

3 files changed

+42
-15
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
*/
2929
public final class ClusterSlotHashUtil {
3030

31-
private static final int SLOT_COUNT = 16384;
31+
public static final int SLOT_COUNT = 16384;
3232

3333
private static final byte SUBKEY_START = '{';
3434
private static final byte SUBKEY_END = '}';

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

+36-11
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.data.redis.connection;
1717

18+
import java.util.Arrays;
19+
import java.util.BitSet;
1820
import java.util.Collection;
1921
import java.util.Collections;
2022
import java.util.LinkedHashSet;
@@ -166,11 +168,12 @@ public static RedisClusterNodeBuilder newRedisClusterNode() {
166168

167169
/**
168170
* @author Christoph Strobl
171+
* @author daihuabin
169172
* @since 1.7
170173
*/
171174
public static class SlotRange {
172175

173-
private final Set<Integer> range;
176+
private BitSet range = new BitSet();
174177

175178
/**
176179
* @param lowerBound must not be {@literal null}.
@@ -181,43 +184,65 @@ public SlotRange(Integer lowerBound, Integer upperBound) {
181184
Assert.notNull(lowerBound, "LowerBound must not be null");
182185
Assert.notNull(upperBound, "UpperBound must not be null");
183186

184-
this.range = new LinkedHashSet<>();
187+
this.range = new BitSet(upperBound + 1);
185188
for (int i = lowerBound; i <= upperBound; i++) {
186-
this.range.add(i);
189+
this.range.set(i);
187190
}
188191
}
189192

190193
public SlotRange(Collection<Integer> range) {
191-
this.range = CollectionUtils.isEmpty(range) ? Collections.emptySet() : new LinkedHashSet<>(range);
194+
if (!CollectionUtils.isEmpty(range)) {
195+
this.range = new BitSet(ClusterSlotHashUtil.SLOT_COUNT);
196+
for (Integer pos : range) {
197+
this.range.set(pos);
198+
}
199+
}
200+
}
201+
202+
public SlotRange(BitSet range) {
203+
this.range = (BitSet) range.clone();
192204
}
193205

194206
@Override
195207
public String toString() {
196-
return range.toString();
208+
return Arrays.toString(this.getSlotsArray());
197209
}
198210

199211
/**
200212
* @param slot
201213
* @return true when slot is part of the range.
202214
*/
203215
public boolean contains(int slot) {
204-
return range.contains(slot);
216+
return range.get(slot);
205217
}
206218

207219
/**
208220
* @return
209221
*/
210222
public Set<Integer> getSlots() {
211-
return Collections.unmodifiableSet(range);
223+
if (range.isEmpty()) {
224+
return Collections.emptySet();
225+
}
226+
LinkedHashSet<Integer> slots = new LinkedHashSet<>(Math.max(2 * range.cardinality(), 11));
227+
for (int i = 0; i < range.length(); i++) {
228+
if (range.get(i)) {
229+
slots.add(i);
230+
}
231+
}
232+
return Collections.unmodifiableSet(slots);
212233
}
213234

214235
public int[] getSlotsArray() {
215-
216-
int[] slots = new int[range.size()];
236+
if (range.isEmpty()) {
237+
return new int[0];
238+
}
239+
int[] slots = new int[range.cardinality()];
217240
int pos = 0;
218241

219-
for (Integer value : range) {
220-
slots[pos++] = value.intValue();
242+
for (int i = 0; i < ClusterSlotHashUtil.SLOT_COUNT; i++) {
243+
if (this.range.get(i)) {
244+
slots[pos++] = i;
245+
}
221246
}
222247

223248
return slots;

src/main/java/org/springframework/data/redis/connection/convert/Converters.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.springframework.data.geo.Metric;
3131
import org.springframework.data.geo.Metrics;
3232
import org.springframework.data.redis.RedisSystemException;
33+
import org.springframework.data.redis.connection.ClusterSlotHashUtil;
3334
import org.springframework.data.redis.connection.DataType;
3435
import org.springframework.data.redis.connection.RedisClusterNode;
3536
import org.springframework.data.redis.connection.RedisClusterNode.Flag;
@@ -57,6 +58,7 @@
5758
* @author Thomas Darimont
5859
* @author Mark Paluch
5960
* @author Christoph Strobl
61+
* @author daihuabin
6062
*/
6163
public abstract class Converters {
6264

@@ -606,7 +608,7 @@ private LinkState parseLinkState(String[] args) {
606608

607609
private SlotRange parseSlotRange(String[] args) {
608610

609-
Set<Integer> slots = new LinkedHashSet<>();
611+
BitSet slots = new BitSet(ClusterSlotHashUtil.SLOT_COUNT);
610612

611613
for (int i = SLOTS_INDEX; i < args.length; i++) {
612614

@@ -623,11 +625,11 @@ private SlotRange parseSlotRange(String[] args) {
623625
int from = Integer.valueOf(slotRange[0]);
624626
int to = Integer.valueOf(slotRange[1]);
625627
for (int slot = from; slot <= to; slot++) {
626-
slots.add(slot);
628+
slots.set(slot);
627629
}
628630
}
629631
} else {
630-
slots.add(Integer.valueOf(raw));
632+
slots.set(Integer.valueOf(raw));
631633
}
632634
}
633635

0 commit comments

Comments
 (0)