Skip to content

Use BitSet instead of LinkedHashSet to improve the performance of SlotRange construction #2525

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
*/
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 = '}';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -166,11 +168,12 @@ public static RedisClusterNodeBuilder newRedisClusterNode() {

/**
* @author Christoph Strobl
* @author daihuabin
* @since 1.7
*/
public static class SlotRange {

private final Set<Integer> range;
private final BitSet range;

/**
* @param lowerBound must not be {@literal null}.
Expand All @@ -181,43 +184,67 @@ public SlotRange(Integer lowerBound, Integer upperBound) {
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<Integer> 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());
}

/**
* @param slot
* @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<Integer> getSlots() {
return Collections.unmodifiableSet(range);
if (range.isEmpty()) {
return Collections.emptySet();
}
LinkedHashSet<Integer> 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
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;
Expand Down Expand Up @@ -57,6 +58,7 @@
* @author Thomas Darimont
* @author Mark Paluch
* @author Christoph Strobl
* @author daihuabin
*/
public abstract class Converters {

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

private SlotRange parseSlotRange(String[] args) {

Set<Integer> slots = new LinkedHashSet<>();
BitSet slots = new BitSet(ClusterSlotHashUtil.SLOT_COUNT);

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

Expand All @@ -623,11 +625,11 @@ private SlotRange parseSlotRange(String[] args) {
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));
}
}

Expand Down