Skip to content

Commit 1059643

Browse files
committed
Fix Cluster sort.
Jedis Cluster sort now considers if the destination key is sharing the same slot as the source key to use same-slot sorting. Additionally, sort results that do not map to the same slot replace the destination key with a list instead of checking the key type and appending results. Closes #2341
1 parent 363e46f commit 1059643

File tree

5 files changed

+35
-43
lines changed

5 files changed

+35
-43
lines changed

src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterKeyCommands.java

+11-16
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
import org.springframework.data.redis.core.ScanOptions;
4949
import org.springframework.lang.Nullable;
5050
import org.springframework.util.Assert;
51-
import org.springframework.util.CollectionUtils;
5251
import org.springframework.util.ObjectUtils;
5352

5453
/**
@@ -431,23 +430,19 @@ public Long sort(byte[] key, SortParameters params, byte[] storeKey) {
431430

432431
Assert.notNull(key, "Key must not be null");
433432

434-
List<byte[]> sorted = sort(key, params);
435-
if (!CollectionUtils.isEmpty(sorted)) {
436-
437-
byte[][] arr = new byte[sorted.size()][];
438-
switch (type(key)) {
439-
440-
case SET:
441-
connection.setCommands().sAdd(storeKey, sorted.toArray(arr));
442-
return 1L;
443-
case LIST:
444-
connection.listCommands().lPush(storeKey, sorted.toArray(arr));
445-
return 1L;
446-
default:
447-
throw new IllegalArgumentException("sort and store is only supported for SET and LIST");
433+
if (ClusterSlotHashUtil.isSameSlotForAllKeys(key, storeKey)) {
434+
try {
435+
return connection.getCluster().sort(key, JedisConverters.toSortingParams(params), storeKey);
436+
} catch (Exception ex) {
437+
throw convertJedisAccessException(ex);
448438
}
449439
}
450-
return 0L;
440+
441+
List<byte[]> sorted = sort(key, params);
442+
byte[][] arr = new byte[sorted.size()][];
443+
connection.keyCommands().unlink(storeKey);
444+
connection.listCommands().lPush(storeKey, sorted.toArray(arr));
445+
return (long) sorted.size();
451446
}
452447

453448
@Nullable

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyCommands.java

+4-17
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import org.springframework.data.redis.core.ScanOptions;
3535
import org.springframework.lang.Nullable;
3636
import org.springframework.util.Assert;
37-
import org.springframework.util.CollectionUtils;
3837

3938
/**
4039
* @author Christoph Strobl
@@ -198,21 +197,9 @@ public Long sort(byte[] key, SortParameters params, byte[] storeKey) {
198197
}
199198

200199
List<byte[]> sorted = sort(key, params);
201-
if (!CollectionUtils.isEmpty(sorted)) {
202-
203-
byte[][] arr = new byte[sorted.size()][];
204-
switch (type(key)) {
205-
206-
case SET:
207-
connection.setCommands().sAdd(storeKey, sorted.toArray(arr));
208-
return 1L;
209-
case LIST:
210-
connection.listCommands().lPush(storeKey, sorted.toArray(arr));
211-
return 1L;
212-
default:
213-
throw new IllegalArgumentException("sort and store is only supported for SET and LIST");
214-
}
215-
}
216-
return 0L;
200+
byte[][] arr = new byte[sorted.size()][];
201+
connection.keyCommands().unlink(storeKey);
202+
connection.listCommands().lPush(storeKey, sorted.toArray(arr));
203+
return (long) sorted.size();
217204
}
218205
}

src/test/java/org/springframework/data/redis/connection/ClusterConnectionTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,8 @@ public interface ClusterConnectionTests {
599599
// DATAREDIS-315
600600
void sortAndStoreShouldAddSortedValuesValuesCorrectly();
601601

602-
// DATAREDIS-315
603-
void sortAndStoreShouldReturnZeroWhenListDoesNotExist();
602+
// DATAREDIS-315, GH-2341
603+
void sortAndStoreShouldReplaceDestinationList();
604604

605605
// DATAREDIS-315
606606
void sortShouldReturnValuesCorrectly();

src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -2031,13 +2031,18 @@ public void sortAndStoreShouldAddSortedValuesValuesCorrectly() {
20312031

20322032
nativeConnection.lpush(KEY_1, VALUE_2, VALUE_1);
20332033

2034-
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(1L);
2034+
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(2L);
20352035
assertThat(nativeConnection.exists(KEY_2_BYTES)).isTrue();
20362036
}
20372037

2038-
@Test // DATAREDIS-315
2039-
public void sortAndStoreShouldReturnZeroWhenListDoesNotExist() {
2040-
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(0L);
2038+
@Test // DATAREDIS-315, GH-2341
2039+
public void sortAndStoreShouldReplaceDestinationList() {
2040+
2041+
nativeConnection.lpush(KEY_1, VALUE_2, VALUE_1);
2042+
nativeConnection.lpush(KEY_2_BYTES, VALUE_3_BYTES);
2043+
2044+
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(2L);
2045+
assertThat(nativeConnection.llen(KEY_2_BYTES)).isEqualTo(2);
20412046
}
20422047

20432048
@Test // DATAREDIS-315

src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -2064,13 +2064,18 @@ public void sortAndStoreShouldAddSortedValuesValuesCorrectly() {
20642064

20652065
nativeConnection.lpush(KEY_1, VALUE_2, VALUE_1);
20662066

2067-
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(1L);
2067+
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(2L);
20682068
assertThat(nativeConnection.exists(KEY_2)).isEqualTo(1L);
20692069
}
20702070

2071-
@Test // DATAREDIS-315
2072-
public void sortAndStoreShouldReturnZeroWhenListDoesNotExist() {
2073-
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(0L);
2071+
@Test // DATAREDIS-315, GH-2341
2072+
public void sortAndStoreShouldReplaceDestinationList() {
2073+
2074+
nativeConnection.lpush(KEY_1, VALUE_2, VALUE_1);
2075+
nativeConnection.lpush(KEY_2, VALUE_3);
2076+
2077+
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(2L);
2078+
assertThat(nativeConnection.llen(KEY_2)).isEqualTo(2);
20742079
}
20752080

20762081
@Test // DATAREDIS-315

0 commit comments

Comments
 (0)