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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user