diff --git a/src/main/java/org/springframework/data/redis/connection/ClusterSlotHashUtil.java b/src/main/java/org/springframework/data/redis/connection/ClusterSlotHashUtil.java index 76b5518c9..e47ab989f 100644 --- a/src/main/java/org/springframework/data/redis/connection/ClusterSlotHashUtil.java +++ b/src/main/java/org/springframework/data/redis/connection/ClusterSlotHashUtil.java @@ -28,7 +28,7 @@ import org.springframework.util.Assert; */ public final class ClusterSlotHashUtil { - private static final int SLOT_COUNT = 16384; + public static final int SLOT_COUNT = 16384; private static final byte SUBKEY_START = '{'; private static final byte SUBKEY_END = '}'; diff --git a/src/main/java/org/springframework/data/redis/connection/RedisClusterNode.java b/src/main/java/org/springframework/data/redis/connection/RedisClusterNode.java index a9637be87..708182612 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisClusterNode.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisClusterNode.java @@ -15,6 +15,8 @@ */ package org.springframework.data.redis.connection; +import java.util.Arrays; +import java.util.BitSet; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; @@ -166,11 +168,12 @@ public class RedisClusterNode extends RedisNode { /** * @author Christoph Strobl + * @author daihuabin * @since 1.7 */ public static class SlotRange { - private final Set range; + private final BitSet range; /** * @param lowerBound must not be {@literal null}. @@ -181,19 +184,30 @@ public class RedisClusterNode extends RedisNode { Assert.notNull(lowerBound, "LowerBound must not be null"); Assert.notNull(upperBound, "UpperBound must not be null"); - this.range = new LinkedHashSet<>(); + this.range = new BitSet(upperBound + 1); for (int i = lowerBound; i <= upperBound; i++) { - this.range.add(i); + this.range.set(i); } } public SlotRange(Collection range) { - this.range = CollectionUtils.isEmpty(range) ? Collections.emptySet() : new LinkedHashSet<>(range); + if (CollectionUtils.isEmpty(range)) { + this.range = new BitSet(0); + } else { + this.range = new BitSet(ClusterSlotHashUtil.SLOT_COUNT); + for (Integer pos : range) { + this.range.set(pos); + } + } + } + + public SlotRange(BitSet range) { + this.range = (BitSet) range.clone(); } @Override public String toString() { - return range.toString(); + return Arrays.toString(this.getSlotsArray()); } /** @@ -201,23 +215,36 @@ public class RedisClusterNode extends RedisNode { * @return true when slot is part of the range. */ public boolean contains(int slot) { - return range.contains(slot); + return range.get(slot); } /** * @return */ public Set getSlots() { - return Collections.unmodifiableSet(range); + if (range.isEmpty()) { + return Collections.emptySet(); + } + LinkedHashSet slots = new LinkedHashSet<>(Math.max(2 * range.cardinality(), 11)); + for (int i = 0; i < range.length(); i++) { + if (range.get(i)) { + slots.add(i); + } + } + return Collections.unmodifiableSet(slots); } public int[] getSlotsArray() { - - int[] slots = new int[range.size()]; + if (range.isEmpty()) { + return new int[0]; + } + int[] slots = new int[range.cardinality()]; int pos = 0; - for (Integer value : range) { - slots[pos++] = value.intValue(); + for (int i = 0; i < ClusterSlotHashUtil.SLOT_COUNT; i++) { + if (this.range.get(i)) { + slots[pos++] = i; + } } return slots; diff --git a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java index e59a2f83b..620f47e37 100644 --- a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java +++ b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java @@ -30,6 +30,7 @@ import org.springframework.data.geo.GeoResults; import org.springframework.data.geo.Metric; import org.springframework.data.geo.Metrics; import org.springframework.data.redis.RedisSystemException; +import org.springframework.data.redis.connection.ClusterSlotHashUtil; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.RedisClusterNode; import org.springframework.data.redis.connection.RedisClusterNode.Flag; @@ -57,6 +58,7 @@ import org.springframework.util.StringUtils; * @author Thomas Darimont * @author Mark Paluch * @author Christoph Strobl + * @author daihuabin */ public abstract class Converters { @@ -606,7 +608,7 @@ public abstract class Converters { private SlotRange parseSlotRange(String[] args) { - Set slots = new LinkedHashSet<>(); + BitSet slots = new BitSet(ClusterSlotHashUtil.SLOT_COUNT); for (int i = SLOTS_INDEX; i < args.length; i++) { @@ -623,11 +625,11 @@ public abstract class Converters { int from = Integer.valueOf(slotRange[0]); int to = Integer.valueOf(slotRange[1]); for (int slot = from; slot <= to; slot++) { - slots.add(slot); + slots.set(slot); } } } else { - slots.add(Integer.valueOf(raw)); + slots.set(Integer.valueOf(raw)); } }