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
This commit is contained in:
Mark Paluch
2022-06-28 11:08:03 +02:00
parent 363e46fd1c
commit 105964394e
5 changed files with 35 additions and 43 deletions

View File

@@ -48,7 +48,6 @@ import org.springframework.data.redis.core.ScanIteration;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
/**
@@ -431,23 +430,19 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
Assert.notNull(key, "Key must not be null");
List<byte[]> sorted = sort(key, params);
if (!CollectionUtils.isEmpty(sorted)) {
byte[][] arr = new byte[sorted.size()][];
switch (type(key)) {
case SET:
connection.setCommands().sAdd(storeKey, sorted.toArray(arr));
return 1L;
case LIST:
connection.listCommands().lPush(storeKey, sorted.toArray(arr));
return 1L;
default:
throw new IllegalArgumentException("sort and store is only supported for SET and LIST");
if (ClusterSlotHashUtil.isSameSlotForAllKeys(key, storeKey)) {
try {
return connection.getCluster().sort(key, JedisConverters.toSortingParams(params), storeKey);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}
return 0L;
List<byte[]> sorted = sort(key, params);
byte[][] arr = new byte[sorted.size()][];
connection.keyCommands().unlink(storeKey);
connection.listCommands().lPush(storeKey, sorted.toArray(arr));
return (long) sorted.size();
}
@Nullable

View File

@@ -34,7 +34,6 @@ import org.springframework.data.redis.core.ScanCursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
* @author Christoph Strobl
@@ -198,21 +197,9 @@ class LettuceClusterKeyCommands extends LettuceKeyCommands {
}
List<byte[]> sorted = sort(key, params);
if (!CollectionUtils.isEmpty(sorted)) {
byte[][] arr = new byte[sorted.size()][];
switch (type(key)) {
case SET:
connection.setCommands().sAdd(storeKey, sorted.toArray(arr));
return 1L;
case LIST:
connection.listCommands().lPush(storeKey, sorted.toArray(arr));
return 1L;
default:
throw new IllegalArgumentException("sort and store is only supported for SET and LIST");
}
}
return 0L;
byte[][] arr = new byte[sorted.size()][];
connection.keyCommands().unlink(storeKey);
connection.listCommands().lPush(storeKey, sorted.toArray(arr));
return (long) sorted.size();
}
}