DATAREDIS-729 - Add support for ZLEXCOUNT.
Original pull request: #569.
This commit is contained in:
@@ -1659,6 +1659,24 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
|
||||
return convertAndReturn(delegate.zUnionStore(destKey, sets), identityConverter);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zLexCount(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
|
||||
*/
|
||||
@Override
|
||||
public Long zLexCount(byte[] key, Range range) {
|
||||
return delegate.zLexCount(key, range);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.StringRedisConnection#zLexCount(java.lang.String, org.springframework.data.redis.connection.RedisZSetCommands.Range)
|
||||
*/
|
||||
@Override
|
||||
public Long zLexCount(String key, Range range) {
|
||||
return delegate.zLexCount(serialize(key), range);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisKeyCommands#pExpire(byte[], long)
|
||||
|
||||
@@ -55,6 +55,7 @@ import org.springframework.lang.Nullable;
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Tugdual Grall
|
||||
* @author Andrey Shlykov
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface DefaultedRedisConnection extends RedisConnection {
|
||||
@@ -1093,6 +1094,13 @@ public interface DefaultedRedisConnection extends RedisConnection {
|
||||
return zSetCommands().zRangeByScore(key, min, max, offset, count);
|
||||
}
|
||||
|
||||
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
|
||||
@Override
|
||||
@Deprecated
|
||||
default Long zLexCount(byte[] key, Range range) {
|
||||
return zSetCommands().zLexCount(key, range);
|
||||
}
|
||||
|
||||
// HASH COMMANDS
|
||||
|
||||
/** @deprecated in favor of {@link RedisConnection#hashCommands()}}. */
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Andrey Shlykov
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface ReactiveZSetCommands {
|
||||
@@ -1935,4 +1936,79 @@ public interface ReactiveZSetCommands {
|
||||
* @see <a href="https://redis.io/commands/zrevrangebylex">Redis Documentation: ZREVRANGEBYLEX</a>
|
||||
*/
|
||||
Flux<CommandResponse<ZRangeByLexCommand, Flux<ByteBuffer>>> zRangeByLex(Publisher<ZRangeByLexCommand> commands);
|
||||
|
||||
/**
|
||||
* {@code ZLEXCOUNT} command parameters.
|
||||
*
|
||||
* @author Andrey Shlykov
|
||||
* @see <a href="https://redis.io/commands/zlexcount">Redis Documentation: ZLEXCOUNT</a>
|
||||
*/
|
||||
class ZLexCountCommand extends KeyCommand {
|
||||
|
||||
private final Range<String> range;
|
||||
|
||||
private ZLexCountCommand(@Nullable ByteBuffer key, Range<String> range) {
|
||||
super(key);
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link ZLexCountCommand} given a {@link Range} of {@link String} to retrieve elements
|
||||
* count.
|
||||
*
|
||||
* @param range must not be {@literal null}.
|
||||
* @return a new {@link ZLexCountCommand} for {@link Range}.
|
||||
*/
|
||||
public static ZLexCountCommand stringsWithin(Range<String> range) {
|
||||
|
||||
Assert.notNull(range, "Range must not be null!");
|
||||
|
||||
return new ZLexCountCommand(null, range);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the {@literal key}. Constructs a new command instance with all previously configured properties.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return a new {@link ZLexCountCommand} with {@literal key} applied.
|
||||
*/
|
||||
public ZLexCountCommand forKey(ByteBuffer key) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
return new ZLexCountCommand(key, range);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public Range<String> getRange() {
|
||||
return range;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Count number of elements within sorted set with value within {@link Range}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param range must not be {@literal null}.
|
||||
* @return
|
||||
* @since 2.4
|
||||
* @see <a href="https://redis.io/commands/zlexcount">Redis Documentation: ZLEXCOUNT</a>
|
||||
*/
|
||||
default Mono<Long> zLexCount(ByteBuffer key, Range<String> range) {
|
||||
return zLexCount(Mono.just(ZLexCountCommand.stringsWithin(range).forKey(key))).next()
|
||||
.map(NumericResponse::getOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count number of elements within sorted set with value within {@link Range}.
|
||||
*
|
||||
* @param commands must not be {@literal null}.
|
||||
* @return
|
||||
* @since 2.4
|
||||
* @see <a href="https://redis.io/commands/zlexcount">Redis Documentation: ZLEXCOUNT</a>
|
||||
*/
|
||||
Flux<NumericResponse<ZLexCountCommand, Long>> zLexCount(Publisher<ZLexCountCommand> commands);
|
||||
|
||||
}
|
||||
|
||||
@@ -1059,4 +1059,16 @@ public interface RedisZSetCommands {
|
||||
@Nullable
|
||||
Set<byte[]> zRevRangeByLex(byte[] key, Range range, Limit limit);
|
||||
|
||||
/**
|
||||
* Count number of elements within sorted set with value between {@code Range#min} and {@code Range#max}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param range must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 2.4
|
||||
* @see <a href="https://redis.io/commands/zlexcount">Redis Documentation: ZLEXCOUNT</a>
|
||||
*/
|
||||
@Nullable
|
||||
Long zLexCount(byte[] key, Range range);
|
||||
|
||||
}
|
||||
|
||||
@@ -1541,6 +1541,19 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
*/
|
||||
Set<String> zRevRangeByLex(String key, Range range, Limit limit);
|
||||
|
||||
/**
|
||||
* Count number of elements within sorted set with value between {@code Range#min} and {@code Range#max}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param range must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 2.4
|
||||
* @see <a href="https://redis.io/commands/zlexcount">Redis Documentation: ZLEXCOUNT</a>
|
||||
* @see RedisZSetCommands#zLexCount(byte[], Range)
|
||||
*/
|
||||
@Nullable
|
||||
Long zLexCount(String key, Range range);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Methods dealing with Redis Hashes
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@@ -795,6 +795,26 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zLexCount(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
|
||||
*/
|
||||
@Override
|
||||
public Long zLexCount(byte[] key, Range range) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(range, "Range must not be null!");
|
||||
|
||||
byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES);
|
||||
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES);
|
||||
|
||||
try {
|
||||
return connection.getCluster().zlexcount(key, min, max);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private DataAccessException convertJedisAccessException(Exception ex) {
|
||||
return connection.convertJedisAccessException(ex);
|
||||
}
|
||||
|
||||
@@ -942,6 +942,34 @@ class JedisZSetCommands implements RedisZSetCommands {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zLexCount(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
|
||||
*/
|
||||
@Override
|
||||
public Long zLexCount(byte[] key, Range range) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(range, "Range must not be null!");
|
||||
|
||||
byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES);
|
||||
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES);
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newJedisResult(connection.getRequiredPipeline().zlexcount(key, min, max)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newJedisResult(connection.getRequiredTransaction().zlexcount(key, min, max)));
|
||||
return null;
|
||||
}
|
||||
return connection.getJedis().zlexcount(key, min, max);
|
||||
} catch (Exception ex) {
|
||||
throw convertJedisAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return connection.isPipelined();
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.springframework.util.ObjectUtils;
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Michele Mancioppi
|
||||
* @author Andrey Shlykov
|
||||
* @since 2.0
|
||||
*/
|
||||
class LettuceReactiveZSetCommands implements ReactiveZSetCommands {
|
||||
@@ -484,6 +485,24 @@ class LettuceReactiveZSetCommands implements ReactiveZSetCommands {
|
||||
}));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.ReactiveZSetCommands#zLexCount(org.reactivestreams.Publisher)
|
||||
*/
|
||||
@Override
|
||||
public Flux<NumericResponse<ZLexCountCommand, Long>> zLexCount(Publisher<ZLexCountCommand> commands) {
|
||||
|
||||
return connection.execute(cmd -> Flux.from(commands).concatMap(command -> {
|
||||
|
||||
Assert.notNull(command.getKey(), "Key must not be null!");
|
||||
Assert.notNull(command.getRange(), "Range must not be null!");
|
||||
|
||||
Mono<Long> result = cmd.zlexcount(command.getKey(), RangeConverter.toRange(command.getRange()));
|
||||
|
||||
return result.map(value -> new NumericResponse<>(command, value));
|
||||
}));
|
||||
}
|
||||
|
||||
private static ZStoreArgs zStoreArgs(@Nullable Aggregate aggregate, @Nullable List<Double> weights) {
|
||||
|
||||
ZStoreArgs args = new ZStoreArgs();
|
||||
|
||||
@@ -927,6 +927,31 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisZSetCommands#zLexCount(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
|
||||
*/
|
||||
@Override
|
||||
public Long zLexCount(byte[] key, Range range) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(range, "Range must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zlexcount(key, LettuceConverters.toRange(range))));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zlexcount(key, LettuceConverters.toRange(range))));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zlexcount(key, LettuceConverters.toRange(range, true));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return connection.isPipelined();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.lang.Nullable;
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Wongoo (望哥)
|
||||
* @author Andrey Shlykov
|
||||
*/
|
||||
public interface BoundZSetOperations<K, V> extends BoundKeyOperations<K> {
|
||||
|
||||
@@ -414,6 +415,17 @@ public interface BoundZSetOperations<K, V> extends BoundKeyOperations<K> {
|
||||
@Nullable
|
||||
Set<V> reverseRangeByLex(Range range, Limit limit);
|
||||
|
||||
/**
|
||||
* Count number of elements within sorted set with value between {@code Range#min} and {@code Range#max}.
|
||||
*
|
||||
* @param range must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 2.4
|
||||
* @see <a href="https://redis.io/commands/zlexcount">Redis Documentation: ZLEXCOUNT</a>
|
||||
*/
|
||||
@Nullable
|
||||
Long lexCount(Range range);
|
||||
|
||||
/**
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Wongoo (望哥)
|
||||
* @author Andrey Shlykov
|
||||
*/
|
||||
class DefaultBoundZSetOperations<K, V> extends DefaultBoundKeyOperations<K> implements BoundZSetOperations<K, V> {
|
||||
|
||||
@@ -329,6 +330,15 @@ class DefaultBoundZSetOperations<K, V> extends DefaultBoundKeyOperations<K> impl
|
||||
return ops.unionAndStore(getKey(), otherKeys, destKey, aggregate, weights);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.BoundZSetOperations#lexCount(org.springframework.data.redis.connection.RedisZSetCommands.Range)
|
||||
*/
|
||||
@Override
|
||||
public Long lexCount(Range range) {
|
||||
return ops.lexCount(getKey(), range);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.BoundKeyOperations#getType()
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
* @author Andrey Shlykov
|
||||
* @since 2.0
|
||||
*/
|
||||
class DefaultReactiveZSetOperations<K, V> implements ReactiveZSetOperations<K, V> {
|
||||
@@ -548,6 +549,20 @@ class DefaultReactiveZSetOperations<K, V> implements ReactiveZSetOperations<K, V
|
||||
return template.createMono(connection -> connection.keyCommands().del(rawKey(key))).map(l -> l != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.core.ReactiveZSetOperations#lexCount(java.lang.Object, org.springframework.data.domain.Range)
|
||||
*/
|
||||
@Override
|
||||
public Mono<Long> lexCount(K key, Range<String> range) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(range, "Range must not be null!");
|
||||
|
||||
|
||||
return createMono(connection -> connection.zLexCount(rawKey(key), range));
|
||||
}
|
||||
|
||||
private <T> Mono<T> createMono(Function<ReactiveZSetCommands, Publisher<T>> function) {
|
||||
|
||||
Assert.notNull(function, "Function must not be null!");
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.springframework.data.redis.connection.RedisZSetCommands.Weights;
|
||||
* @author David Liu
|
||||
* @author Mark Paluch
|
||||
* @author Wongoo (望哥)
|
||||
* @author Andrey Shlykov
|
||||
*/
|
||||
class DefaultZSetOperations<K, V> extends AbstractOperations<K, V> implements ZSetOperations<K, V> {
|
||||
|
||||
@@ -466,4 +467,11 @@ class DefaultZSetOperations<K, V> extends AbstractOperations<K, V> implements ZS
|
||||
|
||||
return execute(connection -> connection.zRangeByScore(rawKey, min, max, offset, count), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long lexCount(K key, Range range) {
|
||||
|
||||
byte[] rawKey = rawKey(key);
|
||||
return execute(connection -> connection.zLexCount(rawKey, range), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
* @author Andrey Shlykov
|
||||
* @see <a href="https://redis.io/commands#zset">Redis Documentation: Sorted Set Commands</a>
|
||||
* @since 2.0
|
||||
*/
|
||||
@@ -461,4 +462,15 @@ public interface ReactiveZSetOperations<K, V> {
|
||||
* @param key must not be {@literal null}.
|
||||
*/
|
||||
Mono<Boolean> delete(K key);
|
||||
|
||||
/**
|
||||
* Count number of elements within sorted set with a value between
|
||||
* {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param range must not be {@literal null}
|
||||
* @return
|
||||
* @see <a href="https://redis.io/commands/ZLEXCOUNT">Redis Documentation: ZLEXCOUNT</a>
|
||||
*/
|
||||
Mono<Long> lexCount(K key, Range<String> range);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.lang.Nullable;
|
||||
* @author Mark Paluch
|
||||
* @author Rosty Kerei
|
||||
* @author Wongoo (望哥)
|
||||
* @author Andrey Shlykov
|
||||
*/
|
||||
public interface ZSetOperations<K, V> {
|
||||
|
||||
@@ -524,6 +525,18 @@ public interface ZSetOperations<K, V> {
|
||||
@Nullable
|
||||
Set<V> reverseRangeByLex(K key, Range range, Limit limit);
|
||||
|
||||
/**
|
||||
* Count number of elements within sorted set with value between {@code Range#min} and {@code Range#max}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param range must not be {@literal null}.
|
||||
* @return {@literal null} when used in pipeline / transaction.
|
||||
* @since 2.4
|
||||
* @see <a href="https://redis.io/commands/zlexcount">Redis Documentation: ZLEXCOUNT</a>
|
||||
*/
|
||||
@Nullable
|
||||
Long lexCount(K key, Range range);
|
||||
|
||||
/**
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
|
||||
* @author Costin Leau
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Andrey Shlykov
|
||||
*/
|
||||
public class DefaultRedisZSet<E> extends AbstractRedisCollection<E> implements RedisZSet<E> {
|
||||
|
||||
@@ -392,6 +393,15 @@ public class DefaultRedisZSet<E> extends AbstractRedisCollection<E> implements R
|
||||
return boundZSetOps.reverseRank(o);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.support.collections.RedisZSet#lexCount(org.springframework.data.redis.connection.RedisZSetCommands.Range)
|
||||
*/
|
||||
@Override
|
||||
public Long lexCount(Range range) {
|
||||
return boundZSetOps.lexCount(range);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.support.collections.RedisZSet#score(java.lang.Object)
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
|
||||
* @author Costin Leau
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
* @author Andrey Shlykov
|
||||
*/
|
||||
public interface RedisZSet<E> extends RedisCollection<E>, Set<E> {
|
||||
|
||||
@@ -167,6 +168,16 @@ public interface RedisZSet<E> extends RedisCollection<E>, Set<E> {
|
||||
*/
|
||||
Double getDefaultScore();
|
||||
|
||||
/**
|
||||
* Count number of elements within sorted set with value between {@code Range#min} and {@code Range#max}.
|
||||
*
|
||||
* @param range must not be {@literal null}.
|
||||
* @return
|
||||
* @since 2.4
|
||||
* @see <a href="https://redis.io/commands/zlexcount">Redis Documentation: ZLEXCOUNT</a>
|
||||
*/
|
||||
Long lexCount(Range range);
|
||||
|
||||
/**
|
||||
* Returns the first (lowest) element currently in this sorted set.
|
||||
*
|
||||
|
||||
@@ -2454,6 +2454,43 @@ public abstract class AbstractConnectionIntegrationTests {
|
||||
assertThat((Set<String>) results.get(13)).contains("c", "b").doesNotContain("a", "d", "e", "f", "g");
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-729
|
||||
@IfProfileValue(name = "redisVersion", value = "2.9.0+")
|
||||
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
|
||||
public void zLexCountTest() {
|
||||
|
||||
actual.add(connection.zAdd("myzset", 0, "a"));
|
||||
actual.add(connection.zAdd("myzset", 0, "b"));
|
||||
actual.add(connection.zAdd("myzset", 0, "c"));
|
||||
actual.add(connection.zAdd("myzset", 0, "d"));
|
||||
actual.add(connection.zAdd("myzset", 0, "e"));
|
||||
actual.add(connection.zAdd("myzset", 0, "f"));
|
||||
actual.add(connection.zAdd("myzset", 0, "g"));
|
||||
|
||||
actual.add(connection.zLexCount("myzset", Range.unbounded()));
|
||||
actual.add(connection.zLexCount("myzset", Range.range().lt("c")));
|
||||
actual.add(connection.zLexCount("myzset", Range.range().lte("c")));
|
||||
actual.add(connection.zLexCount("myzset", Range.range().gte("aaa").lt("g")));
|
||||
actual.add(connection.zLexCount("myzset", Range.range().gte("e")));
|
||||
|
||||
List<Object> results = getResults();
|
||||
|
||||
Long count = (Long) results.get(7);
|
||||
assertThat(count).isEqualTo(7);
|
||||
|
||||
count = (Long) results.get(8);
|
||||
assertThat(count).isEqualTo(2);
|
||||
|
||||
count = (Long) results.get(9);
|
||||
assertThat(count).isEqualTo(3);
|
||||
|
||||
count = (Long) results.get(10);
|
||||
assertThat(count).isEqualTo(5);
|
||||
|
||||
count = (Long) results.get(11);
|
||||
assertThat(count).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class) // DATAREDIS-316, DATAREDIS-692
|
||||
@WithRedisDriver({ RedisDriver.JEDIS, RedisDriver.LETTUCE })
|
||||
public void setWithExpirationAndNullOpionShouldThrowException() {
|
||||
|
||||
@@ -48,6 +48,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
* @author Andrey Shlykov
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -693,4 +694,32 @@ public class DefaultReactiveZSetOperationsIntegrationTests<K, V> {
|
||||
.expectNext(0L) //
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-729
|
||||
public void lexCount() {
|
||||
|
||||
assumeTrue(serializer instanceof StringRedisSerializer);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
|
||||
zSetOperations.add(key, (V) "a", 0).as(StepVerifier::create).expectNext(true).verifyComplete();
|
||||
zSetOperations.add(key, (V) "b", 0).as(StepVerifier::create).expectNext(true).verifyComplete();
|
||||
zSetOperations.add(key, (V) "c", 0).as(StepVerifier::create).expectNext(true).verifyComplete();
|
||||
zSetOperations.add(key, (V) "d", 0).as(StepVerifier::create).expectNext(true).verifyComplete();
|
||||
zSetOperations.add(key, (V) "e", 0).as(StepVerifier::create).expectNext(true).verifyComplete();
|
||||
zSetOperations.add(key, (V) "f", 0).as(StepVerifier::create).expectNext(true).verifyComplete();
|
||||
zSetOperations.add(key, (V) "g", 0).as(StepVerifier::create).expectNext(true).verifyComplete();
|
||||
|
||||
zSetOperations.lexCount(key, Range.unbounded()).as(StepVerifier::create)
|
||||
.expectNext(7L)
|
||||
.verifyComplete();
|
||||
|
||||
zSetOperations.lexCount(key, Range.leftOpen("b", "f")).as(StepVerifier::create)
|
||||
.expectNext(4L)
|
||||
.verifyComplete();
|
||||
|
||||
zSetOperations.lexCount(key, Range.rightOpen("b", "f")).as(StepVerifier::create)
|
||||
.expectNext(4L)
|
||||
.verifyComplete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ import org.springframework.test.annotation.IfProfileValue;
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Wongoo (望哥)
|
||||
* @author Andrey Shlykov
|
||||
* @param <K> Key type
|
||||
* @param <V> Value type
|
||||
*/
|
||||
@@ -459,4 +460,40 @@ public class DefaultZSetOperationsTests<K, V> {
|
||||
|
||||
assertThat(zSetOps.score(key1, value1)).isCloseTo(6.0, offset(0.1));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-729
|
||||
public void testLexCountUnbounded() {
|
||||
|
||||
assumeThat(valueFactory).isOfAnyClassIn(DoubleObjectFactory.class, DoubleAsStringObjectFactory.class,
|
||||
LongAsStringObjectFactory.class, LongObjectFactory.class);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
V value3 = valueFactory.instance();
|
||||
|
||||
zSetOps.add(key, value1, 0);
|
||||
zSetOps.add(key, value2, 0);
|
||||
zSetOps.add(key, value3, 0);
|
||||
|
||||
assertThat(zSetOps.lexCount(key, RedisZSetCommands.Range.unbounded())).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-729
|
||||
public void testLexCountBounded() {
|
||||
|
||||
assumeThat(valueFactory).isOfAnyClassIn(DoubleObjectFactory.class, DoubleAsStringObjectFactory.class,
|
||||
LongAsStringObjectFactory.class, LongObjectFactory.class);
|
||||
|
||||
K key = keyFactory.instance();
|
||||
V value1 = valueFactory.instance();
|
||||
V value2 = valueFactory.instance();
|
||||
V value3 = valueFactory.instance();
|
||||
|
||||
zSetOps.add(key, value1, 0);
|
||||
zSetOps.add(key, value2, 0);
|
||||
zSetOps.add(key, value3, 0);
|
||||
|
||||
assertThat(zSetOps.lexCount(key, RedisZSetCommands.Range.range().gt(value1))).isEqualTo(2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ import org.springframework.test.annotation.IfProfileValue;
|
||||
* @author Jennifer Hickey
|
||||
* @author Thomas Darimont
|
||||
* @author Mark Paluch
|
||||
* @author Andrey Shlykov
|
||||
*/
|
||||
public abstract class AbstractRedisZSetTest<T> extends AbstractRedisCollectionTests<T> {
|
||||
|
||||
@@ -660,4 +661,38 @@ public abstract class AbstractRedisZSetTest<T> extends AbstractRedisCollectionTe
|
||||
cursor.close();
|
||||
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-729
|
||||
public void testLexCountUnbounded() {
|
||||
|
||||
assumeThat(factory).isOfAnyClassIn(DoubleObjectFactory.class, DoubleAsStringObjectFactory.class,
|
||||
LongAsStringObjectFactory.class, LongObjectFactory.class);
|
||||
|
||||
T t1 = getT();
|
||||
T t2 = getT();
|
||||
T t3 = getT();
|
||||
|
||||
zSet.add(t1, 1);
|
||||
zSet.add(t2, 1);
|
||||
zSet.add(t3, 1);
|
||||
|
||||
assertThat(zSet.lexCount(RedisZSetCommands.Range.unbounded())).isEqualTo(Long.valueOf(3));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-729
|
||||
public void testLexCountBounded() {
|
||||
|
||||
assumeThat(factory).isOfAnyClassIn(DoubleObjectFactory.class, DoubleAsStringObjectFactory.class,
|
||||
LongAsStringObjectFactory.class, LongObjectFactory.class);
|
||||
|
||||
T t1 = getT();
|
||||
T t2 = getT();
|
||||
T t3 = getT();
|
||||
|
||||
zSet.add(t1, 1);
|
||||
zSet.add(t2, 1);
|
||||
zSet.add(t3, 1);
|
||||
|
||||
assertThat(zSet.lexCount(RedisZSetCommands.Range.range().gt(t1))).isEqualTo(Long.valueOf(2));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user