DATAREDIS-529 - Polishing.
Accept varargs byte arrays instead of Collection of byte arrays. Bypass own routing for exists single-slot execution in Redis Cluster. Replace parallel stream execution of exists(…) with sequential ClusterCommandExecutor dispatch. Reorder methods in ClusterConnectionTests by name. Adapt Javadoc. Original pull request: #281.
This commit is contained in:
@@ -300,15 +300,15 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
|
||||
*/
|
||||
@Override
|
||||
public Long exists(String... keys) {
|
||||
return convertAndReturn(delegate.exists(Arrays.asList(serializeMulti(keys))), identityConverter);
|
||||
return convertAndReturn(delegate.exists(serializeMulti(keys)), identityConverter);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisKeyCommands#exists(java.util.Collection)
|
||||
* @see org.springframework.data.redis.connection.RedisKeyCommands#exists(byte[][])
|
||||
*/
|
||||
@Override
|
||||
public Long exists(Collection<byte[]> keys) {
|
||||
public Long exists(byte[]... keys) {
|
||||
return convertAndReturn(delegate.exists(keys), identityConverter);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -58,7 +57,7 @@ public interface DefaultedRedisConnection extends RedisConnection {
|
||||
/** @deprecated in favor of {@link RedisConnection#keyCommands()}. */
|
||||
@Override
|
||||
@Deprecated
|
||||
default Long exists(Collection<byte[]> keys) {
|
||||
default Long exists(byte[]... keys) {
|
||||
return keyCommands().exists(keys);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -46,20 +44,21 @@ public interface RedisKeyCommands {
|
||||
default Boolean exists(byte[] key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Long count = exists(Collections.singleton(key));
|
||||
Long count = exists(new byte[][] { key });
|
||||
return count != null ? count > 0 : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count how many of the given {@code keys} exists. Providing the very same {@code key} more than once also counts
|
||||
* Count how many of the given {@code keys} exist. Providing the very same {@code key} more than once also counts
|
||||
* multiple times.
|
||||
*
|
||||
* @param keys must not be {@literal null}.
|
||||
* @return the number of keys existing among the ones specified as arguments.
|
||||
* @return the number of keys existing among the ones specified as arguments. {@literal null} when used in pipeline /
|
||||
* transaction.
|
||||
* @since 2.1
|
||||
*/
|
||||
@Nullable
|
||||
Long exists(Collection<byte[]> keys);
|
||||
Long exists(byte[]... keys);
|
||||
|
||||
/**
|
||||
* Delete given {@code keys}.
|
||||
|
||||
@@ -92,12 +92,12 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
Boolean exists(String key);
|
||||
|
||||
/**
|
||||
* Count how many of the if given {@code keys} exists.
|
||||
* Count how many of the given {@code keys} exist.
|
||||
*
|
||||
* @param keys must not be {@literal null}.
|
||||
* @return
|
||||
* @see <a href="http://redis.io/commands/exists">Redis Documentation: EXISTS</a>
|
||||
* @see RedisKeyCommands#exists(java.util.Collection)
|
||||
* @see RedisKeyCommands#exists(byte[][])
|
||||
* @since 2.1
|
||||
*/
|
||||
@Nullable
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection.jedis;
|
||||
|
||||
import redis.clients.jedis.BinaryJedis;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -62,7 +64,8 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
|
||||
@Override
|
||||
public Long del(byte[]... keys) {
|
||||
|
||||
Assert.noNullElements(keys, "Keys must not be null or contain null key!");
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements!");
|
||||
|
||||
if (ClusterSlotHashUtil.isSameSlotForAllKeys(keys)) {
|
||||
try {
|
||||
@@ -473,26 +476,26 @@ class JedisClusterKeyCommands implements RedisKeyCommands {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisKeyCommands#exists(java.util.Collection)
|
||||
* @see org.springframework.data.redis.connection.RedisKeyCommands#exists(byte[][])
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Long exists(Collection<byte[]> keys) {
|
||||
public Long exists(byte[]... keys) {
|
||||
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
|
||||
return keys.stream() //
|
||||
.parallel()
|
||||
.map(key -> connection.getClusterCommandExecutor()
|
||||
.executeCommandOnSingleNode((JedisClusterCommandCallback<Boolean>) client -> client.exists(key),
|
||||
connection.getTopologyProvider().getTopology().getKeyServingMasterNode(key))
|
||||
.getValue())
|
||||
.mapToLong(val -> ObjectUtils.nullSafeEquals(val, Boolean.TRUE) ? 1L : 0L).sum();
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
if (ClusterSlotHashUtil.isSameSlotForAllKeys(keys)) {
|
||||
try {
|
||||
return connection.getCluster().exists(keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
return connection.getClusterCommandExecutor()
|
||||
.executeMultiKeyCommand((JedisMultiKeyClusterCommandCallback<Boolean>) BinaryJedis::exists, Arrays.asList(keys))
|
||||
.resultsAsList().stream().mapToLong(val -> ObjectUtils.nullSafeEquals(val, Boolean.TRUE) ? 1 : 0).sum();
|
||||
}
|
||||
|
||||
private DataAccessException convertJedisAccessException(Exception ex) {
|
||||
|
||||
@@ -20,7 +20,6 @@ import lombok.RequiredArgsConstructor;
|
||||
import redis.clients.jedis.ScanParams;
|
||||
import redis.clients.jedis.SortingParams;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -73,26 +72,27 @@ class JedisKeyCommands implements RedisKeyCommands {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisKeyCommands#exists(java.util.Collection)
|
||||
* @see org.springframework.data.redis.connection.RedisKeyCommands#exists(byte[][])
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Long exists(Collection<byte[]> keys) {
|
||||
public Long exists(byte[]... keys) {
|
||||
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(
|
||||
connection.newJedisResult(connection.getRequiredPipeline().exists(keys.toArray(new byte[keys.size()][]))));
|
||||
connection.newJedisResult(connection.getRequiredPipeline().exists(keys)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection
|
||||
.newJedisResult(connection.getRequiredTransaction().exists(keys.toArray(new byte[keys.size()][]))));
|
||||
.newJedisResult(connection.getRequiredTransaction().exists(keys)));
|
||||
return null;
|
||||
}
|
||||
return connection.getJedis().exists(keys.toArray(new byte[keys.size()][]));
|
||||
return connection.getJedis().exists(keys);
|
||||
} catch (Exception ex) {
|
||||
throw connection.convertJedisAccessException(ex);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -80,24 +79,25 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisKeyCommands#exists(java.util.Collection)
|
||||
* @see org.springframework.data.redis.connection.RedisKeyCommands#exists(byte[][])
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Long exists(Collection<byte[]> keys) {
|
||||
public Long exists(byte[]... keys) {
|
||||
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().exists(keys.toArray(new byte[keys.size()][]))));
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().exists(keys)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceTxResult(getAsyncConnection().exists(keys.toArray(new byte[keys.size()][]))));
|
||||
transaction(connection.newLettuceTxResult(getAsyncConnection().exists(keys)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().exists(keys.toArray(new byte[keys.size()][]));
|
||||
return getConnection().exists(keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ public interface RedisOperations<K, V> {
|
||||
Boolean hasKey(K key);
|
||||
|
||||
/**
|
||||
* Count the number of {@code keys} that exists.
|
||||
* Count the number of {@code keys} that exist.
|
||||
*
|
||||
* @param keys must not be {@literal null}.
|
||||
* @return The number of keys existing among the ones specified as arguments. Keys mentioned multiple times and
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.data.redis.core;
|
||||
import java.io.Closeable;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
@@ -750,7 +749,7 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
|
||||
byte[][] rawKeys = rawKeys(keys);
|
||||
return execute(connection -> connection.exists(Arrays.asList(rawKeys)), true);
|
||||
return execute(connection -> connection.exists(rawKeys), true);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1327,7 +1326,7 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
|
||||
* Set the {@link ClassLoader} to be used for the default {@link JdkSerializationRedisSerializer} in case no other
|
||||
* {@link RedisSerializer} is explicitly set as the default one.
|
||||
*
|
||||
* @param resourceLoader can be {@literal null}.
|
||||
* @param classLoader can be {@literal null}.
|
||||
* @see org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader
|
||||
* @since 1.8
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user