Skip to content

Commit 0d0df32

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 a810d37 commit 0d0df32

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

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
import org.springframework.data.redis.core.ScanOptions;
4848
import org.springframework.lang.Nullable;
4949
import org.springframework.util.Assert;
50-
import org.springframework.util.CollectionUtils;
5150
import org.springframework.util.ObjectUtils;
5251

5352
/**
@@ -541,23 +540,19 @@ public Long sort(byte[] key, SortParameters params, byte[] storeKey) {
541540

542541
Assert.notNull(key, "Key must not be null!");
543542

544-
List<byte[]> sorted = sort(key, params);
545-
if (!CollectionUtils.isEmpty(sorted)) {
546-
547-
byte[][] arr = new byte[sorted.size()][];
548-
switch (type(key)) {
549-
550-
case SET:
551-
connection.setCommands().sAdd(storeKey, sorted.toArray(arr));
552-
return 1L;
553-
case LIST:
554-
connection.listCommands().lPush(storeKey, sorted.toArray(arr));
555-
return 1L;
556-
default:
557-
throw new IllegalArgumentException("sort and store is only supported for SET and LIST");
543+
if (ClusterSlotHashUtil.isSameSlotForAllKeys(key, storeKey)) {
544+
try {
545+
return connection.getCluster().sort(key, JedisConverters.toSortingParams(params), storeKey);
546+
} catch (Exception ex) {
547+
throw convertJedisAccessException(ex);
558548
}
559549
}
560-
return 0L;
550+
551+
List<byte[]> sorted = sort(key, params);
552+
byte[][] arr = new byte[sorted.size()][];
553+
connection.keyCommands().unlink(storeKey);
554+
connection.listCommands().lPush(storeKey, sorted.toArray(arr));
555+
return (long) sorted.size();
561556
}
562557

563558
/*

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

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import org.springframework.data.redis.core.ScanOptions;
3434
import org.springframework.lang.Nullable;
3535
import org.springframework.util.Assert;
36-
import org.springframework.util.CollectionUtils;
3736

3837
/**
3938
* @author Christoph Strobl
@@ -229,21 +228,9 @@ public Long sort(byte[] key, SortParameters params, byte[] storeKey) {
229228
}
230229

231230
List<byte[]> sorted = sort(key, params);
232-
if (!CollectionUtils.isEmpty(sorted)) {
233-
234-
byte[][] arr = new byte[sorted.size()][];
235-
switch (type(key)) {
236-
237-
case SET:
238-
connection.setCommands().sAdd(storeKey, sorted.toArray(arr));
239-
return 1L;
240-
case LIST:
241-
connection.listCommands().lPush(storeKey, sorted.toArray(arr));
242-
return 1L;
243-
default:
244-
throw new IllegalArgumentException("sort and store is only supported for SET and LIST");
245-
}
246-
}
247-
return 0L;
231+
byte[][] arr = new byte[sorted.size()][];
232+
connection.keyCommands().unlink(storeKey);
233+
connection.listCommands().lPush(storeKey, sorted.toArray(arr));
234+
return (long) sorted.size();
248235
}
249236
}

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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,13 +2028,18 @@ public void sortAndStoreShouldAddSortedValuesValuesCorrectly() {
20282028

20292029
nativeConnection.lpush(KEY_1, VALUE_2, VALUE_1);
20302030

2031-
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(1L);
2031+
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(2L);
20322032
assertThat(nativeConnection.exists(KEY_2_BYTES)).isTrue();
20332033
}
20342034

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

20402045
@Test // DATAREDIS-315

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,13 +2059,18 @@ public void sortAndStoreShouldAddSortedValuesValuesCorrectly() {
20592059

20602060
nativeConnection.lpush(KEY_1, VALUE_2, VALUE_1);
20612061

2062-
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(1L);
2062+
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(2L);
20632063
assertThat(nativeConnection.exists(KEY_2)).isEqualTo(1L);
20642064
}
20652065

2066-
@Test // DATAREDIS-315
2067-
public void sortAndStoreShouldReturnZeroWhenListDoesNotExist() {
2068-
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(0L);
2066+
@Test // DATAREDIS-315, GH-2341
2067+
public void sortAndStoreShouldReplaceDestinationList() {
2068+
2069+
nativeConnection.lpush(KEY_1, VALUE_2, VALUE_1);
2070+
nativeConnection.lpush(KEY_2, VALUE_3);
2071+
2072+
assertThat(clusterConnection.sort(KEY_1_BYTES, new DefaultSortParameters().alpha(), KEY_2_BYTES)).isEqualTo(2L);
2073+
assertThat(nativeConnection.llen(KEY_2)).isEqualTo(2);
20692074
}
20702075

20712076
@Test // DATAREDIS-315

0 commit comments

Comments
 (0)