Polishing.

Add reactive ZRANGESTORE support. Support rangeAndStore in RedisZSet.

Refine assertion messages. Refine overloads.

Original pull request: #2370.
See #2345
This commit is contained in:
Mark Paluch
2022-09-23 12:05:42 +02:00
parent 40d078f66d
commit 62932e2b47
21 changed files with 1420 additions and 156 deletions

View File

@@ -2711,6 +2711,12 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
return convertAndReturn(delegate.zRevRangeByLex(key, range, limit), Converters.identityConverter());
}
@Override
public Set<String> zRevRangeByLex(String key, org.springframework.data.domain.Range<String> range,
org.springframework.data.redis.connection.Limit limit) {
return convertAndReturn(delegate.zRevRangeByLex(serialize(key), serialize(range), limit), byteSetToStringSet);
}
@Override
public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey,
org.springframework.data.domain.Range<byte[]> range,
@@ -2721,16 +2727,21 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
@Override
public Long zRangeStoreByLex(String dstKey, String srcKey,
org.springframework.data.domain.Range<String> range,
org.springframework.data.redis.connection.Limit limit) {
org.springframework.data.domain.Range<String> range, org.springframework.data.redis.connection.Limit limit) {
return convertAndReturn(delegate.zRangeStoreByLex(serialize(dstKey), serialize(srcKey), serialize(range), limit),
Converters.identityConverter());
}
@Override
public Long zRangeStoreByScore(String dstKey, String srcKey, double min, double max,
org.springframework.data.redis.connection.Limit limit) {
return convertAndReturn(delegate.zRangeStoreByScore(serialize(dstKey), serialize(srcKey), min, max, limit),
public Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit) {
return convertAndReturn(delegate.zRangeStoreRevByLex(dstKey, srcKey, range, limit), Converters.identityConverter());
}
@Override
public Long zRangeStoreRevByLex(String dstKey, String srcKey, org.springframework.data.domain.Range<String> range,
org.springframework.data.redis.connection.Limit limit) {
return convertAndReturn(delegate.zRangeStoreRevByLex(serialize(dstKey), serialize(srcKey), serialize(range), limit),
Converters.identityConverter());
}
@@ -2743,9 +2754,24 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
}
@Override
public Set<String> zRevRangeByLex(String key, org.springframework.data.domain.Range<String> range,
public Long zRangeStoreByScore(String dstKey, String srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit) {
return convertAndReturn(delegate.zRevRangeByLex(serialize(key), serialize(range), limit), byteSetToStringSet);
return convertAndReturn(delegate.zRangeStoreByScore(serialize(dstKey), serialize(srcKey), range, limit),
Converters.identityConverter());
}
@Override
public Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit) {
return convertAndReturn(delegate.zRangeStoreRevByScore(dstKey, srcKey, range, limit),
Converters.identityConverter());
}
@Override
public Long zRangeStoreRevByScore(String dstKey, String srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit) {
return convertAndReturn(delegate.zRangeStoreRevByScore(serialize(dstKey), serialize(srcKey), range, limit),
Converters.identityConverter());
}
@Override

View File

@@ -1846,6 +1846,14 @@ public interface DefaultedRedisConnection extends RedisCommands, RedisCommandsPr
return zSetCommands().zRangeStoreByLex(dstKey, srcKey, range, limit);
}
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
@Override
@Deprecated
default Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit) {
return zSetCommands().zRangeStoreRevByLex(dstKey, srcKey, range, limit);
}
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
@Override
@Deprecated
@@ -1855,4 +1863,12 @@ public interface DefaultedRedisConnection extends RedisCommands, RedisCommandsPr
return zSetCommands().zRangeStoreByScore(dstKey, srcKey, range, limit);
}
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
@Override
@Deprecated
default Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit) {
return zSetCommands().zRangeStoreRevByScore(dstKey, srcKey, range, limit);
}
}

View File

@@ -52,6 +52,10 @@ public class Limit {
return this.equals(UNLIMITED);
}
public boolean isLimited() {
return !isUnlimited();
}
/**
* @return new {@link Limit} indicating no limit;
* @since 1.3

View File

@@ -902,6 +902,250 @@ public interface ReactiveZSetCommands {
*/
Flux<CommandResponse<ZRangeCommand, Flux<Tuple>>> zRange(Publisher<ZRangeCommand> commands);
/**
* {@code ZRANGESTORE} command parameters.
*
* @author Mark Paluch
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
class ZRangeStoreCommand extends KeyCommand {
private final ByteBuffer destKey;
private final RangeMode rangeMode;
private final Range<?> range;
private final Direction direction;
private final Limit limit;
private ZRangeStoreCommand(@Nullable ByteBuffer srcKey, @Nullable ByteBuffer destKey, RangeMode rangeMode,
Range<?> range, Direction direction, Limit limit) {
super(srcKey);
this.destKey = destKey;
this.rangeMode = rangeMode;
this.range = range;
this.direction = direction;
this.limit = limit;
}
/**
* Creates a new {@link ZRangeStoreCommand} given a {@link Range} to obtain elements ordered from the lowest to the
* highest score.
*
* @param range must not be {@literal null}.
* @return a new {@link ZRangeCommand} for {@link Tuple}.
*/
public static ZRangeStoreCommand scoreWithin(Range<Double> range) {
Assert.notNull(range, "Range must not be null");
return new ZRangeStoreCommand(null, null, RangeMode.ByScore, range, Direction.ASC, Limit.unlimited());
}
/**
* Creates a new {@link ZRangeStoreCommand} given a {@link Range} to obtain elements ordered from the highest to the
* lowest score.
*
* @param range must not be {@literal null}.
* @return a new {@link ZRangeStoreCommand} for {@link Tuple}.
*/
public static ZRangeStoreCommand reverseScoreWithin(Range<Double> range) {
Assert.notNull(range, "Range must not be null");
return new ZRangeStoreCommand(null, null, RangeMode.ByScore, range, Direction.DESC, Limit.unlimited());
}
/**
* Creates a new {@link ZRangeStoreCommand} given a {@link Range} to obtain elements ordered from the lowest to the
* highest lexicographical value.
*
* @param range must not be {@literal null}.
* @return a new {@link ZRangeCommand} for {@link Tuple}.
*/
public static ZRangeStoreCommand valueWithin(Range<String> range) {
Assert.notNull(range, "Range must not be null");
return new ZRangeStoreCommand(null, null, RangeMode.ByLex, range, Direction.ASC, Limit.unlimited());
}
/**
* Creates a new {@link ZRangeStoreCommand} given a {@link Range} to obtain elements ordered from the highest to the
* lowest lexicographical value.
*
* @param range must not be {@literal null}.
* @return a new {@link ZRangeStoreCommand} for {@link Tuple}.
*/
public static ZRangeStoreCommand reverseValueWithin(Range<String> range) {
Assert.notNull(range, "Range must not be null");
return new ZRangeStoreCommand(null, null, RangeMode.ByLex, range, Direction.DESC, Limit.unlimited());
}
/**
* 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 ZRangeStoreCommand} with {@literal key} applied.
*/
public ZRangeStoreCommand from(ByteBuffer key) {
Assert.notNull(key, "Key must not be null");
return new ZRangeStoreCommand(key, destKey, rangeMode, range, direction, limit);
}
/**
* 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 ZRangeStoreCommand} with {@literal key} applied.
*/
public ZRangeStoreCommand to(ByteBuffer key) {
Assert.notNull(key, "Key must not be null");
return new ZRangeStoreCommand(getKey(), key, rangeMode, range, direction, limit);
}
/**
* Applies the {@literal limit}. Constructs a new command instance with all previously configured properties.
*
* @param limit must not be {@literal null}.
* @return a new {@link ZRangeStoreCommand} with {@literal key} applied.
*/
public ZRangeStoreCommand limit(Limit limit) {
Assert.notNull(limit, "Limit must not be null");
return new ZRangeStoreCommand(getKey(), getDestKey(), rangeMode, range, direction, limit);
}
public ByteBuffer getDestKey() {
return destKey;
}
public RangeMode getRangeMode() {
return rangeMode;
}
public Range<?> getRange() {
return range;
}
public Direction getDirection() {
return direction;
}
public Limit getLimit() {
return limit;
}
public enum RangeMode {
ByScore, ByLex,
}
}
/**
* Add elements from {@code srcKey} by score {@literal range} to {@code destKey}.
*
* @param srcKey must not be {@literal null}.
* @param destKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
default Mono<Long> zRangeStoreByScore(ByteBuffer srcKey, ByteBuffer destKey, Range<Double> range, Limit limit) {
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(destKey, "Destination key must not be null");
Assert.notNull(range, "Range must not be null");
Assert.notNull(limit, "Limit must not be null");
return zRangeStore(Mono.just(ZRangeStoreCommand.scoreWithin(range).from(srcKey).to(destKey).limit(limit))) //
.flatMap(CommandResponse::getOutput).next();
}
/**
* Add elements from {@code srcKey} by lexicographical {@literal range} to {@code destKey}.
*
* @param srcKey must not be {@literal null}.
* @param destKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
default Mono<Long> zRangeStoreByLex(ByteBuffer srcKey, ByteBuffer destKey, Range<String> range, Limit limit) {
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(destKey, "Destination key must not be null");
Assert.notNull(range, "Range must not be null");
Assert.notNull(limit, "Limit must not be null");
return zRangeStore(Mono.just(ZRangeStoreCommand.valueWithin(range).from(srcKey).to(destKey).limit(limit))) //
.flatMap(CommandResponse::getOutput).next();
}
/**
* Add elements from {@code srcKey} by reverse score {@literal range} to {@code destKey}.
*
* @param srcKey must not be {@literal null}.
* @param destKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
default Mono<Long> zRangeStoreRevByScore(ByteBuffer srcKey, ByteBuffer destKey, Range<Double> range, Limit limit) {
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(destKey, "Destination key must not be null");
Assert.notNull(range, "Range must not be null");
Assert.notNull(limit, "Limit must not be null");
return zRangeStore(Mono.just(ZRangeStoreCommand.reverseScoreWithin(range).from(srcKey).to(destKey).limit(limit))) //
.flatMap(CommandResponse::getOutput).next();
}
/**
* Add elements from {@code srcKey} by reverse lexicographical {@literal range} to {@code destKey}.
*
* @param srcKey must not be {@literal null}.
* @param destKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
default Mono<Long> zRangeStoreRevByLex(ByteBuffer srcKey, ByteBuffer destKey, Range<String> range, Limit limit) {
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(destKey, "Destination key must not be null");
Assert.notNull(range, "Range must not be null");
Assert.notNull(limit, "Limit must not be null");
return zRangeStore(Mono.just(ZRangeStoreCommand.reverseValueWithin(range).from(srcKey).to(destKey).limit(limit))) //
.flatMap(CommandResponse::getOutput).next();
}
/**
* Get set of {@link Tuple}s in {@literal range} from sorted set.
*
* @param commands must not be {@literal null}.
* @return
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
Flux<CommandResponse<ZRangeStoreCommand, Mono<Long>>> zRangeStore(Publisher<ZRangeStoreCommand> commands);
/**
* {@literal ZRANGEBYSCORE}/{@literal ZREVRANGEBYSCORE}.
*

View File

@@ -1379,8 +1379,7 @@ public interface RedisZSetCommands {
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey,
org.springframework.data.domain.Range<byte[]> range) {
default Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range) {
return zRangeStoreByLex(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited());
}
@@ -1396,43 +1395,38 @@ public interface RedisZSetCommands {
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey,
org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit);
Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit);
/**
* This command is like ZRANGE, but stores the result in the {@literal dstKey} destination key.
* This command is like ZRANGE … REV , but stores the result in the {@literal dstKey} destination key.
*
* @param dstKey must not be {@literal null}.
* @param srcKey must not be {@literal null}.
* @param min minimal inclusive score
* @param max maximal inclusive score
* @param range must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, double min, double max) {
return zRangeStoreByScore(dstKey, srcKey, org.springframework.data.domain.Range.closed(min, max));
default Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range) {
return zRangeStoreRevByLex(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited());
}
/**
* This command is like ZRANGE, but stores the result in the {@literal dstKey} destination key.
* This command is like ZRANGE … REV , but stores the result in the {@literal dstKey} destination key.
*
* @param dstKey must not be {@literal null}.
* @param srcKey must not be {@literal null}.
* @param min minimal inclusive score
* @param max maximal inclusive score
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, double min, double max,
org.springframework.data.redis.connection.Limit limit) {
return zRangeStoreByScore(dstKey, srcKey, org.springframework.data.domain.Range.closed(min, max), limit);
}
Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit);
/**
* This command is like ZRANGE, but stores the result in the {@literal dstKey} destination key.
@@ -1445,10 +1439,8 @@ public interface RedisZSetCommands {
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey,
org.springframework.data.domain.Range<Number> range) {
return zRangeStoreByScore(dstKey, srcKey, range,
org.springframework.data.redis.connection.Limit.unlimited());
default Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range) {
return zRangeStoreByScore(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited());
}
/**
@@ -1463,8 +1455,38 @@ public interface RedisZSetCommands {
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey,
org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit);
Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit);
/**
* This command is like ZRANGE … REV, but stores the result in the {@literal dstKey} destination key.
*
* @param dstKey must not be {@literal null}.
* @param srcKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey,
org.springframework.data.domain.Range<Number> range) {
return zRangeStoreRevByScore(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited());
}
/**
* This command is like ZRANGE … REV, but stores the result in the {@literal dstKey} destination key.
*
* @param dstKey must not be {@literal null}.
* @param srcKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit);
}

View File

@@ -1999,8 +1999,7 @@ public interface StringRedisConnection extends RedisConnection {
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long zRangeStoreByLex(String dstKey, String srcKey,
org.springframework.data.domain.Range<String> range) {
default Long zRangeStoreByLex(String dstKey, String srcKey, org.springframework.data.domain.Range<String> range) {
return zRangeStoreByLex(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited());
}
@@ -2016,25 +2015,52 @@ public interface StringRedisConnection extends RedisConnection {
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long zRangeStoreByLex(String dstKey, String srcKey,
org.springframework.data.domain.Range<String> range,
org.springframework.data.redis.connection.Limit limit);
Long zRangeStoreByLex(String dstKey, String srcKey, org.springframework.data.domain.Range<String> range,
org.springframework.data.redis.connection.Limit limit);
/**
* This command is like ZRANGE … REV , but stores the result in the {@literal dstKey} destination key.
*
* @param dstKey must not be {@literal null}.
* @param srcKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long zRangeStoreRevByLex(String dstKey, String srcKey, org.springframework.data.domain.Range<String> range) {
return zRangeStoreRevByLex(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited());
}
/**
* This command is like ZRANGE … REV , but stores the result in the {@literal dstKey} destination key.
*
* @param dstKey must not be {@literal null}.
* @param srcKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long zRangeStoreRevByLex(String dstKey, String srcKey, org.springframework.data.domain.Range<String> range,
org.springframework.data.redis.connection.Limit limit);
/**
* This command is like ZRANGE, but stores the result in the {@literal dstKey} destination key.
*
* @param dstKey must not be {@literal null}.
* @param srcKey must not be {@literal null}.
* @param min minimal inclusive score
* @param max maximal inclusive score
* @param range must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long zRangeStoreByScore(String dstKey, String srcKey, double min, double max) {
return zRangeStoreByScore(dstKey, srcKey, min, max, org.springframework.data.redis.connection.Limit.unlimited());
default Long zRangeStoreByScore(String dstKey, String srcKey, org.springframework.data.domain.Range<Number> range) {
return zRangeStoreByScore(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited());
}
/**
@@ -2042,16 +2068,46 @@ public interface StringRedisConnection extends RedisConnection {
*
* @param dstKey must not be {@literal null}.
* @param srcKey must not be {@literal null}.
* @param min minimal inclusive score
* @param max maximal inclusive score
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long zRangeStoreByScore(String dstKey, String srcKey, double min, double max,
org.springframework.data.redis.connection.Limit limit);
Long zRangeStoreByScore(String dstKey, String srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit);
/**
* This command is like ZRANGE … REV, but stores the result in the {@literal dstKey} destination key.
*
* @param dstKey must not be {@literal null}.
* @param srcKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long zRangeStoreRevByScore(String dstKey, String srcKey,
org.springframework.data.domain.Range<Number> range) {
return zRangeStoreRevByScore(dstKey, srcKey, range, org.springframework.data.redis.connection.Limit.unlimited());
}
/**
* This command is like ZRANGE … REV, but stores the result in the {@literal dstKey} destination key.
*
* @param dstKey must not be {@literal null}.
* @param srcKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long zRangeStoreRevByScore(String dstKey, String srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit);
// -------------------------------------------------------------------------
// Methods dealing with Redis Hashes

View File

@@ -497,19 +497,37 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
}
@Override
public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey,
org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit) {
public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit) {
return zRangeStoreByLex(dstKey, srcKey, range, limit, false);
}
@Override
public Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit) {
return zRangeStoreByLex(dstKey, srcKey, range, limit, true);
}
private Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit, boolean rev) {
Assert.notNull(dstKey, "Destination key must not be null");
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(range, "Range for ZRANGESTORE BYLEX must not be null");
Assert.notNull(range, "Range must not be null");
Assert.notNull(limit, "Limit must not be null. Use Limit.unlimited() instead.");
byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getLowerBound(), JedisConverters.MINUS_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getUpperBound(), JedisConverters.PLUS_BYTES);
ZRangeParams zRangeParams = new ZRangeParams(Protocol.Keyword.BYLEX, min, max)
.limit(limit.getOffset(), limit.getCount());
ZRangeParams zRangeParams = new ZRangeParams(Protocol.Keyword.BYLEX, min, max);
if (limit.isLimited()) {
zRangeParams = zRangeParams.limit(limit.getOffset(), limit.getCount());
}
if (rev) {
zRangeParams = zRangeParams.rev();
}
try {
return connection.getCluster().zrangestore(dstKey, srcKey, zRangeParams);
@@ -518,22 +536,42 @@ class JedisClusterZSetCommands implements RedisZSetCommands {
}
}
@Nullable
@Override
public Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey,
org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit) {
public Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit) {
return zRangeStoreByScore(dstKey, srcKey, range, limit, false);
}
@Nullable
@Override
public Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit) {
return zRangeStoreByScore(dstKey, srcKey, range, limit, true);
}
private Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit, boolean rev) {
Assert.notNull(dstKey, "Destination key must not be null");
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(range, "Range for ZRANGESTORE BYSCORE must not be null");
Assert.notNull(range, "Range for must not be null");
Assert.notNull(limit, "Limit must not be null. Use Limit.unlimited() instead.");
byte[] min = JedisConverters
.boundaryToBytesForZRange(range.getLowerBound(), JedisConverters.NEGATIVE_INFINITY_BYTES);
byte[] max = JedisConverters
.boundaryToBytesForZRange(range.getUpperBound(), JedisConverters.POSITIVE_INFINITY_BYTES);
byte[] min = JedisConverters.boundaryToBytesForZRange(range.getLowerBound(),
JedisConverters.NEGATIVE_INFINITY_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getUpperBound(),
JedisConverters.POSITIVE_INFINITY_BYTES);
ZRangeParams zRangeParams = new ZRangeParams(Protocol.Keyword.BYSCORE, min, max)
.limit(limit.getOffset(), limit.getCount());
ZRangeParams zRangeParams = new ZRangeParams(Protocol.Keyword.BYSCORE, min, max);
if (limit.isLimited()) {
zRangeParams = zRangeParams.limit(limit.getOffset(), limit.getCount());
}
if (rev) {
zRangeParams = zRangeParams.rev();
}
try {
return connection.getCluster().zrangestore(dstKey, srcKey, zRangeParams);

View File

@@ -680,47 +680,63 @@ class JedisZSetCommands implements RedisZSetCommands {
}
@Override
public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey,
org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit) {
Assert.notNull(dstKey, "Destination key must not be null");
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(range, "Range for ZRANGESTORE BYLEX must not be null");
Assert.notNull(limit, "Limit must not be null. Use Limit.unlimited() instead.");
byte[] min = JedisConverters
.boundaryToBytesForZRangeByLex(range.getLowerBound(), JedisConverters.MINUS_BYTES);
byte[] max = JedisConverters
.boundaryToBytesForZRangeByLex(range.getUpperBound(), JedisConverters.PLUS_BYTES);
ZRangeParams zRangeParams = new ZRangeParams(Protocol.Keyword.BYLEX, min, max)
.limit(limit.getOffset(), limit.getCount());
return connection.invoke().just(Jedis::zrangestore, PipelineBinaryCommands::zrangestore,
dstKey, srcKey, zRangeParams);
public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit) {
return zRangeStoreByLex(dstKey, srcKey, range, limit, false);
}
@Override
public Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey,
org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit) {
public Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit) {
return zRangeStoreByLex(dstKey, srcKey, range, limit, true);
}
private Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit, boolean rev) {
Assert.notNull(dstKey, "Destination key must not be null");
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(range, "Range for ZRANGESTORE BYSCORE must not be null");
Assert.notNull(range, "Range must not be null");
Assert.notNull(limit, "Limit must not be null. Use Limit.unlimited() instead.");
byte[] min = JedisConverters
.boundaryToBytesForZRange(range.getLowerBound(), JedisConverters.NEGATIVE_INFINITY_BYTES);
byte[] max = JedisConverters
.boundaryToBytesForZRange(range.getUpperBound(), JedisConverters.POSITIVE_INFINITY_BYTES);
byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getLowerBound(), JedisConverters.MINUS_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getUpperBound(), JedisConverters.PLUS_BYTES);
ZRangeParams zRangeParams = new ZRangeParams(Protocol.Keyword.BYSCORE, min, max)
.limit(limit.getOffset(), limit.getCount());
ZRangeParams zRangeParams = toZRangeParams(Protocol.Keyword.BYLEX, min, max, limit, rev);
return connection.invoke().just(Jedis::zrangestore, PipelineBinaryCommands::zrangestore,
dstKey, srcKey, zRangeParams);
return connection.invoke().just(Jedis::zrangestore, PipelineBinaryCommands::zrangestore, dstKey, srcKey,
zRangeParams);
}
@Override
public Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit) {
return zRangeStoreByScore(dstKey, srcKey, range, limit, false);
}
@Override
public Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit) {
return zRangeStoreByScore(dstKey, srcKey, range, limit, true);
}
private Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit, boolean rev) {
Assert.notNull(dstKey, "Destination key must not be null");
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(range, "Range must not be null");
Assert.notNull(limit, "Limit must not be null. Use Limit.unlimited() instead.");
byte[] min = JedisConverters.boundaryToBytesForZRange(range.getLowerBound(),
JedisConverters.NEGATIVE_INFINITY_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRange(range.getUpperBound(),
JedisConverters.POSITIVE_INFINITY_BYTES);
ZRangeParams zRangeParams = toZRangeParams(Protocol.Keyword.BYSCORE, min, max, limit, rev);
return connection.invoke().just(Jedis::zrangestore, PipelineBinaryCommands::zrangestore, dstKey, srcKey,
zRangeParams);
}
private boolean isPipelined() {
@@ -735,6 +751,23 @@ class JedisZSetCommands implements RedisZSetCommands {
return new ZParams().weights(weights.toArray()).aggregate(ZParams.Aggregate.valueOf(aggregate.name()));
}
static ZRangeParams toZRangeParams(Protocol.Keyword by, byte[] min, byte[] max,
org.springframework.data.redis.connection.Limit limit, boolean rev) {
ZRangeParams zRangeParams;
if (rev) {
zRangeParams = new ZRangeParams(by, max, min).rev();
} else {
zRangeParams = new ZRangeParams(by, min, max);
}
if (limit.isLimited()) {
zRangeParams = zRangeParams.limit(limit.getOffset(), limit.getCount());
}
return zRangeParams;
}
/**
* Workaround for broken Jedis BZPOP signature.
*

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.redis.connection.lettuce;
import io.lettuce.core.Limit;
import io.lettuce.core.Range;
import io.lettuce.core.ScanStream;
import io.lettuce.core.ScoredValue;
@@ -169,8 +170,8 @@ class LettuceReactiveZSetCommands implements ReactiveZSetCommands {
Assert.notNull(command.getKey(), "Key must not be null");
return new CommandResponse<>(command, cmd.zrandmemberWithScores(command.getKey(), command.getCount())
.map(this::toTuple));
return new CommandResponse<>(command,
cmd.zrandmemberWithScores(command.getKey(), command.getCount()).map(this::toTuple));
}));
}
@@ -225,6 +226,43 @@ class LettuceReactiveZSetCommands implements ReactiveZSetCommands {
}));
}
@Override
@SuppressWarnings("unchecked")
public Flux<CommandResponse<ZRangeStoreCommand, Mono<Long>>> zRangeStore(Publisher<ZRangeStoreCommand> commands) {
return connection.execute(cmd -> Flux.from(commands).concatMap(command -> {
Assert.notNull(command.getKey(), "Source key must not be null");
Assert.notNull(command.getDestKey(), "Destination key must not be null");
Assert.notNull(command.getRange(), "Range must not be null");
Assert.notNull(command.getLimit(), "Limit must not be null");
Limit limit = LettuceConverters.toLimit(command.getLimit());
Mono<Long> result;
if (command.getDirection() == Direction.ASC) {
switch (command.getRangeMode()) {
case ByScore -> result = cmd.zrangestorebyscore(command.getDestKey(), command.getKey(),
(Range<? extends Number>) LettuceConverters.toRange(command.getRange()), limit);
case ByLex -> result = cmd.zrangestorebylex(command.getDestKey(), command.getKey(),
RangeConverter.toRange(command.getRange()), limit);
default -> throw new IllegalStateException("Unsupported value: " + command.getRangeMode());
}
} else {
switch (command.getRangeMode()) {
case ByScore -> result = cmd.zrevrangestorebyscore(command.getDestKey(), command.getKey(),
(Range<? extends Number>) LettuceConverters.toRange(command.getRange()), limit);
case ByLex -> result = cmd.zrevrangestorebylex(command.getDestKey(), command.getKey(),
RangeConverter.toRange(command.getRange()), limit);
default -> throw new IllegalStateException("Unsupported value: " + command.getRangeMode());
}
}
return Mono.just(new CommandResponse<>(command, result));
}));
}
@Override
public Flux<CommandResponse<ZRangeByScoreCommand, Flux<Tuple>>> zRangeByScore(
Publisher<ZRangeByScoreCommand> commands) {
@@ -362,7 +400,7 @@ class LettuceReactiveZSetCommands implements ReactiveZSetCommands {
Assert.notNull(command.getKey(), "Key must not be null");
Assert.notNull(command.getTimeout(), "Timeout must not be null");
if(command.getTimeUnit() == TimeUnit.MILLISECONDS) {
if (command.getTimeUnit() == TimeUnit.MILLISECONDS) {
double timeout = TimeoutUtils.toDoubleSeconds(command.getTimeout(), command.getTimeUnit());

View File

@@ -174,14 +174,13 @@ class LettuceZSetCommands implements RedisZSetCommands {
Assert.notNull(limit, "Limit must not be null");
if (limit.isUnlimited()) {
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrangebyscoreWithScores, key,
LettuceConverters.<Number> toRange(range)).toSet(LettuceConverters::toTuple);
return connection.invoke()
.fromMany(RedisSortedSetAsyncCommands::zrangebyscoreWithScores, key, LettuceConverters.toRange(range))
.toSet(LettuceConverters::toTuple);
}
return connection
.invoke().fromMany(RedisSortedSetAsyncCommands::zrangebyscoreWithScores, key,
LettuceConverters.<Number> toRange(range), LettuceConverters.toLimit(limit))
.toSet(LettuceConverters::toTuple);
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrangebyscoreWithScores, key,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)).toSet(LettuceConverters::toTuple);
}
@@ -214,12 +213,11 @@ class LettuceZSetCommands implements RedisZSetCommands {
if (limit.isUnlimited()) {
return connection.invoke()
.fromMany(RedisSortedSetAsyncCommands::zrevrangebyscore, key, LettuceConverters.<Number> toRange(range))
.toSet();
.fromMany(RedisSortedSetAsyncCommands::zrevrangebyscore, key, LettuceConverters.toRange(range)).toSet();
}
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrevrangebyscore, key,
LettuceConverters.<Number> toRange(range), LettuceConverters.toLimit(limit)).toSet();
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)).toSet();
}
@@ -232,14 +230,13 @@ class LettuceZSetCommands implements RedisZSetCommands {
Assert.notNull(limit, "Limit must not be null");
if (limit.isUnlimited()) {
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrevrangebyscoreWithScores, key,
LettuceConverters.<Number> toRange(range)).toSet(LettuceConverters::toTuple);
return connection.invoke()
.fromMany(RedisSortedSetAsyncCommands::zrevrangebyscoreWithScores, key, LettuceConverters.toRange(range))
.toSet(LettuceConverters::toTuple);
}
return connection.invoke()
.fromMany(RedisSortedSetAsyncCommands::zrevrangebyscoreWithScores, key,
LettuceConverters.<Number> toRange(range), LettuceConverters.toLimit(limit))
.toSet(LettuceConverters::toTuple);
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrevrangebyscoreWithScores, key,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)).toSet(LettuceConverters::toTuple);
}
@@ -248,8 +245,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null");
return connection.invoke().just(RedisSortedSetAsyncCommands::zcount, key,
LettuceConverters.<Number> toRange(range));
return connection.invoke().just(RedisSortedSetAsyncCommands::zcount, key, LettuceConverters.toRange(range));
}
@Override
@@ -259,7 +255,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
Assert.notNull(range, "Range must not be null");
return connection.invoke().just(RedisSortedSetAsyncCommands::zlexcount, key,
LettuceConverters.<byte[]> toRange(range, true));
LettuceConverters.toRange(range, true));
}
@Nullable
@@ -288,7 +284,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null");
Assert.notNull(unit, "TimeUnit must not be null");
if(TimeUnit.MILLISECONDS == unit) {
if (TimeUnit.MILLISECONDS == unit) {
return connection.invoke(connection.getAsyncDedicatedConnection())
.from(RedisSortedSetAsyncCommands::bzpopmin, TimeoutUtils.toDoubleSeconds(timeout, unit), key)
@@ -326,7 +322,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
Assert.notNull(key, "Key must not be null");
Assert.notNull(unit, "TimeUnit must not be null");
if(TimeUnit.MILLISECONDS == unit) {
if (TimeUnit.MILLISECONDS == unit) {
return connection.invoke(connection.getAsyncDedicatedConnection())
.from(RedisSortedSetAsyncCommands::bzpopmax, TimeoutUtils.toDoubleSeconds(timeout, unit), key)
@@ -379,7 +375,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
Assert.notNull(range, "Range must not be null for ZREMRANGEBYLEX");
return connection.invoke().just(RedisSortedSetAsyncCommands::zremrangebylex, key,
LettuceConverters.<byte[]> toRange(range, true));
LettuceConverters.toRange(range, true));
}
@Override
@@ -389,7 +385,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
Assert.notNull(range, "Range for ZREMRANGEBYSCORE must not be null");
return connection.invoke().just(RedisSortedSetAsyncCommands::zremrangebyscore, key,
LettuceConverters.<Number> toRange(range));
LettuceConverters.toRange(range));
}
@Override
@@ -601,11 +597,11 @@ class LettuceZSetCommands implements RedisZSetCommands {
if (limit.isUnlimited()) {
return connection.invoke()
.fromMany(RedisSortedSetAsyncCommands::zrangebyscore, key, LettuceConverters.<Number> toRange(range)).toSet();
.fromMany(RedisSortedSetAsyncCommands::zrangebyscore, key, LettuceConverters.toRange(range)).toSet();
}
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrangebyscore, key,
LettuceConverters.<Number> toRange(range), LettuceConverters.toLimit(limit)).toSet();
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)).toSet();
}
@Override
@@ -618,12 +614,11 @@ class LettuceZSetCommands implements RedisZSetCommands {
if (limit.isUnlimited()) {
return connection.invoke()
.fromMany(RedisSortedSetAsyncCommands::zrangebylex, key, LettuceConverters.<byte[]> toRange(range, true))
.toSet();
.fromMany(RedisSortedSetAsyncCommands::zrangebylex, key, LettuceConverters.toRange(range, true)).toSet();
}
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrangebylex, key,
LettuceConverters.<byte[]> toRange(range, true), LettuceConverters.toLimit(limit)).toSet();
LettuceConverters.toRange(range, true), LettuceConverters.toLimit(limit)).toSet();
}
@Override
@@ -631,47 +626,70 @@ class LettuceZSetCommands implements RedisZSetCommands {
org.springframework.data.redis.connection.Limit limit) {
Assert.notNull(key, "Key must not be null");
Assert.notNull(range, "Range for ZREVRANGEBYLEX must not be null");
Assert.notNull(range, "Range for must not be null");
Assert.notNull(limit, "Limit must not be null");
if (limit.isUnlimited()) {
return connection.invoke()
.fromMany(RedisSortedSetAsyncCommands::zrevrangebylex, key, LettuceConverters.<byte[]> toRange(range, true))
.toSet();
.fromMany(RedisSortedSetAsyncCommands::zrevrangebylex, key, LettuceConverters.toRange(range, true)).toSet();
}
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrevrangebylex, key,
LettuceConverters.<byte[]> toRange(range, true), LettuceConverters.toLimit(limit)).toSet();
LettuceConverters.toRange(range, true), LettuceConverters.toLimit(limit)).toSet();
}
@Override
public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey,
org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit) {
public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit) {
Assert.notNull(dstKey, "Destination key must not be null");
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(range, "Range for ZRANGESTORE BYLEX must not be null");
Assert.notNull(range, "Range for must not be null");
Assert.notNull(limit, "Limit must not be null. Use Limit.unlimited() instead.");
return connection.invoke().just(RedisSortedSetAsyncCommands::zrangestorebylex, dstKey, srcKey,
LettuceConverters.<byte[]>toRange(range, true), LettuceConverters.toLimit(limit));
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit));
}
@Override
public Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey,
org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit) {
public Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
org.springframework.data.redis.connection.Limit limit) {
Assert.notNull(dstKey, "Destination key must not be null");
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(range, "Range for ZRANGESTORE BYSCORE must not be null");
Assert.notNull(range, "Range for must not be null");
Assert.notNull(limit, "Limit must not be null. Use Limit.unlimited() instead.");
return connection.invoke().just(RedisSortedSetAsyncCommands::zrevrangestorebylex, dstKey, srcKey,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit));
}
@Override
public Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit) {
Assert.notNull(dstKey, "Destination key must not be null");
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(range, "Range for must not be null");
Assert.notNull(limit, "Limit must not be null. Use Limit.unlimited() instead.");
return connection.invoke().just(RedisSortedSetAsyncCommands::zrangestorebyscore, dstKey, srcKey,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit));
}
@Override
public Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
org.springframework.data.redis.connection.Limit limit) {
Assert.notNull(dstKey, "Destination key must not be null");
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(range, "Range for must not be null");
Assert.notNull(limit, "Limit must not be null. Use Limit.unlimited() instead.");
return connection.invoke().just(RedisSortedSetAsyncCommands::zrevrangestorebyscore, dstKey, srcKey,
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit));
}
public RedisClusterCommands<byte[], byte[]> getConnection() {
return connection.getConnection();
}

View File

@@ -932,8 +932,8 @@ public interface BoundZSetOperations<K, V> extends BoundKeyOperations<K> {
/**
* Get all elements {@literal n} elements, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with reverse lexicographical ordering from {@literal ZSET} having a value
* between {@link org.springframework.data.redis.connection.RedisZSetCommands.Range#getMin()} and
* {@link Limit#getOffset()} with reverse lexicographical ordering from {@literal ZSET} having a value between
* {@link org.springframework.data.redis.connection.RedisZSetCommands.Range#getMin()} and
* {@link org.springframework.data.redis.connection.RedisZSetCommands.Range#getMax()}.
*
* @param range must not be {@literal null}.
@@ -945,7 +945,8 @@ public interface BoundZSetOperations<K, V> extends BoundKeyOperations<K> {
*/
@Nullable
@Deprecated(since = "3.0", forRemoval = true)
default Set<V> reverseRangeByLex(org.springframework.data.redis.connection.RedisZSetCommands.Range range, Limit limit) {
default Set<V> reverseRangeByLex(org.springframework.data.redis.connection.RedisZSetCommands.Range range,
Limit limit) {
return reverseRangeByLex(range.toRange(), limit);
}
@@ -963,6 +964,133 @@ public interface BoundZSetOperations<K, V> extends BoundKeyOperations<K> {
@Nullable
Set<V> reverseRangeByLex(Range<String> range, Limit limit);
/**
* Store all elements at {@code dstKey} with lexicographical ordering from {@literal ZSET} at the bound key with a
* value between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #rangeByLex(Range)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long rangeAndStoreByLex(K dstKey, Range<String> range) {
return rangeAndStoreByLex(dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with lexicographical ordering from {@literal ZSET} at the bound key with a value between
* {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #rangeByLex(Range, Limit)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long rangeAndStoreByLex(K dstKey, Range<String> range, Limit limit);
/**
* Store all elements at {@code dstKey} with reverse lexicographical ordering from {@literal ZSET} at the bound key
* with a value between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #reverseRangeByLex(Range)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long reverseRangeAndStoreByLex(K dstKey, Range<String> range) {
return reverseRangeAndStoreByLex(dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with reverse lexicographical ordering from {@literal ZSET} at the bound key with a value
* between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #reverseRangeByLex(Range, Limit)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long reverseRangeAndStoreByLex(K dstKey, Range<String> range, Limit limit);
/**
* Store all elements at {@code dstKey} with ordering by score from {@literal ZSET} at the bound key with a score
* between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #rangeByScore(double, double)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long rangeAndStoreByScore(K dstKey, Range<Number> range) {
return rangeAndStoreByScore(dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with ordering by score from {@literal ZSET} at the bound key with a score between
* {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #rangeByScore(double, double)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long rangeAndStoreByScore(K dstKey, Range<Number> range, Limit limit);
/**
* Store all elements at {@code dstKey} with reverse ordering by score from {@literal ZSET} at the bound key with a
* score between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #reverseRangeByScore(double, double)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long reverseRangeAndStoreByScore(K dstKey, Range<Number> range) {
return reverseRangeAndStoreByScore(dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with reverse ordering by score from {@literal ZSET} at the bound key with a score between
* {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long reverseRangeAndStoreByScore(K dstKey, Range<Number> range, Limit limit);
/**
* @return never {@literal null}.
*/

View File

@@ -288,6 +288,50 @@ class DefaultReactiveZSetOperations<K, V> implements ReactiveZSetOperations<K, V
connection -> connection.zRevRangeByScoreWithScores(rawKey(key), range, limit).map(this::readTypedTuple));
}
@Override
public Mono<Long> rangeAndStoreByLex(K srcKey, K dstKey, Range<String> range, Limit limit) {
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(dstKey, "Destination key must not be null");
Assert.notNull(range, "Range must not be null");
Assert.notNull(limit, "Limit must not be null");
return createMono(connection -> connection.zRangeStoreByLex(rawKey(srcKey), rawKey(dstKey), range, limit));
}
@Override
public Mono<Long> reverseRangeAndStoreByLex(K srcKey, K dstKey, Range<String> range, Limit limit) {
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(dstKey, "Destination key must not be null");
Assert.notNull(range, "Range must not be null");
Assert.notNull(limit, "Limit must not be null");
return createMono(connection -> connection.zRangeStoreRevByLex(rawKey(srcKey), rawKey(dstKey), range, limit));
}
@Override
public Mono<Long> rangeAndStoreByScore(K srcKey, K dstKey, Range<Double> range, Limit limit) {
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(dstKey, "Destination key must not be null");
Assert.notNull(range, "Range must not be null");
Assert.notNull(limit, "Limit must not be null");
return createMono(connection -> connection.zRangeStoreByScore(rawKey(srcKey), rawKey(dstKey), range, limit));
}
@Override
public Mono<Long> reverseRangeAndStoreByScore(K srcKey, K dstKey, Range<Double> range, Limit limit) {
Assert.notNull(srcKey, "Source key must not be null");
Assert.notNull(dstKey, "Destination key must not be null");
Assert.notNull(range, "Range must not be null");
Assert.notNull(limit, "Limit must not be null");
return createMono(connection -> connection.zRangeStoreRevByScore(rawKey(srcKey), rawKey(dstKey), range, limit));
}
@Override
public Flux<TypedTuple<V>> scan(K key, ScanOptions options) {

View File

@@ -228,19 +228,33 @@ class DefaultZSetOperations<K, V> extends AbstractOperations<K, V> implements ZS
}
@Override
public Long rangeStoreByLex(K dstKey, K srcKey, Range<String> range, Limit limit) {
public Long rangeAndStoreByLex(K srcKey, K dstKey, Range<String> range, Limit limit) {
byte[] rawDstKey = rawKey(dstKey);
byte[] rawSrcKey = rawKey(srcKey);
return execute(connection -> connection.zRangeStoreByLex(rawDstKey, rawSrcKey, serialize(range), limit));
}
@Override
public Long rangeStoreByScore(K dstKey, K srcKey, Range<Number> range, Limit limit) {
public Long reverseRangeAndStoreByLex(K srcKey, K dstKey, Range<String> range, Limit limit) {
byte[] rawDstKey = rawKey(dstKey);
byte[] rawSrcKey = rawKey(srcKey);
return execute(connection -> connection.zRangeStoreRevByLex(rawDstKey, rawSrcKey, serialize(range), limit));
}
@Override
public Long rangeAndStoreByScore(K srcKey, K dstKey, Range<Number> range, Limit limit) {
byte[] rawDstKey = rawKey(dstKey);
byte[] rawSrcKey = rawKey(srcKey);
return execute(connection -> connection.zRangeStoreByScore(rawDstKey, rawSrcKey, range, limit));
}
@Override
public Long reverseRangeAndStoreByScore(K srcKey, K dstKey, Range<Number> range, Limit limit) {
byte[] rawDstKey = rawKey(dstKey);
byte[] rawSrcKey = rawKey(srcKey);
return execute(connection -> connection.zRangeStoreRevByScore(rawDstKey, rawSrcKey, range, limit));
}
@Override
public Set<V> rangeByScore(K key, double min, double max) {

View File

@@ -29,6 +29,7 @@ import org.springframework.data.redis.connection.zset.Aggregate;
import org.springframework.data.redis.connection.zset.Tuple;
import org.springframework.data.redis.connection.zset.Weights;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
import org.springframework.lang.Nullable;
/**
* Redis ZSet/sorted set specific operations.
@@ -300,6 +301,128 @@ public interface ReactiveZSetOperations<K, V> {
*/
Flux<TypedTuple<V>> reverseRangeByScoreWithScores(K key, Range<Double> range, Limit limit);
/**
* Store all elements at {@code dstKey} with lexicographical ordering from {@literal ZSET} at {@code srcKey} with a
* value between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of stored elements.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
default Mono<Long> rangeAndStoreByLex(K srcKey, K dstKey, Range<String> range) {
return rangeAndStoreByLex(srcKey, dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with lexicographical ordering from {@literal ZSET} at {@code srcKey} with a value between
* {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return the number of stored elements.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
Mono<Long> rangeAndStoreByLex(K srcKey, K dstKey, Range<String> range, Limit limit);
/**
* Store all elements at {@code dstKey} with reverse lexicographical ordering from {@literal ZSET} at {@code srcKey}
* with a value between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of stored elements.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
default Mono<Long> reverseRangeAndStoreByLex(K srcKey, K dstKey, Range<String> range) {
return reverseRangeAndStoreByLex(srcKey, dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with reverse lexicographical ordering from {@literal ZSET} at {@code srcKey} with a value
* between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return the number of stored elements.
* @since 3.0
* @see #reverseRangeByLex(Object, Range, Limit)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
Mono<Long> reverseRangeAndStoreByLex(K srcKey, K dstKey, Range<String> range, Limit limit);
/**
* Store all elements at {@code dstKey} with ordering by score from {@literal ZSET} at {@code srcKey} with a score
* between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of stored elements.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Mono<Long> rangeAndStoreByScore(K srcKey, K dstKey, Range<Double> range) {
return rangeAndStoreByScore(srcKey, dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with ordering by score from {@literal ZSET} at {@code srcKey} with a score between
* {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return the number of stored elements.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
Mono<Long> rangeAndStoreByScore(K srcKey, K dstKey, Range<Double> range, Limit limit);
/**
* Store all elements at {@code dstKey} with reverse ordering by score from {@literal ZSET} at {@code srcKey} with a
* score between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of stored elements.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
default Mono<Long> reverseRangeAndStoreByScore(K srcKey, K dstKey, Range<Double> range) {
return reverseRangeAndStoreByScore(srcKey, dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with reverse ordering by score from {@literal ZSET} at {@code srcKey} with a score
* between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return the number of stored elements.
* @since 3.0
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
Mono<Long> reverseRangeAndStoreByScore(K srcKey, K dstKey, Range<Double> range, Limit limit);
/**
* Use a {@link Flux} to iterate over entries in the sorted set at {@code key}. The resulting {@link Flux} acts as a
* cursor and issues {@code ZSCAN} commands itself as long as the subscriber signals demand.

View File

@@ -1101,7 +1101,7 @@ public interface ZSetOperations<K, V> {
* between {@link org.springframework.data.redis.connection.RedisZSetCommands.Range#getMin()} and
* {@link org.springframework.data.redis.connection.RedisZSetCommands.Range#getMax()}.
*
* @param key must not be {@literal null}
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit can be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
@@ -1121,7 +1121,7 @@ public interface ZSetOperations<K, V> {
* {@link Limit#getOffset()} with reverse lexicographical ordering from {@literal ZSET} at {@code key} with a value
* between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param key must not be {@literal null}
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit can be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
@@ -1131,11 +1131,141 @@ public interface ZSetOperations<K, V> {
@Nullable
Set<V> reverseRangeByLex(K key, Range<String> range, Limit limit);
/**
* Store all elements at {@code dstKey} with lexicographical ordering from {@literal ZSET} at {@code srcKey} with a
* value between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #rangeByLex(Object, Range)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long rangeStoreByLex(K dstKey, K srcKey, Range<String> range, Limit limit);
default Long rangeAndStoreByLex(K srcKey, K dstKey, Range<String> range) {
return rangeAndStoreByLex(srcKey, dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with lexicographical ordering from {@literal ZSET} at {@code srcKey} with a value between
* {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #rangeByLex(Object, Range, Limit)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long rangeStoreByScore(K dstKey, K srcKey, Range<Number> range, Limit limit);
Long rangeAndStoreByLex(K srcKey, K dstKey, Range<String> range, Limit limit);
/**
* Store all elements at {@code dstKey} with reverse lexicographical ordering from {@literal ZSET} at {@code srcKey}
* with a value between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #reverseRangeByLex(Object, Range)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long reverseRangeAndStoreByLex(K srcKey, K dstKey, Range<String> range) {
return reverseRangeAndStoreByLex(srcKey, dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with reverse lexicographical ordering from {@literal ZSET} at {@code srcKey} with a value
* between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #reverseRangeByLex(Object, Range, Limit)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long reverseRangeAndStoreByLex(K srcKey, K dstKey, Range<String> range, Limit limit);
/**
* Store all elements at {@code dstKey} with ordering by score from {@literal ZSET} at {@code srcKey} with a score
* between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #rangeByScore(Object, double, double)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long rangeAndStoreByScore(K srcKey, K dstKey, Range<Number> range) {
return rangeAndStoreByScore(srcKey, dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with ordering by score from {@literal ZSET} at {@code srcKey} with a score between
* {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #rangeByScore(Object, double, double, long, long)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long rangeAndStoreByScore(K srcKey, K dstKey, Range<Number> range, Limit limit);
/**
* Store all elements at {@code dstKey} with reverse ordering by score from {@literal ZSET} at {@code srcKey} with a
* score between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #reverseRangeByScore(Object, double, double)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
default Long reverseRangeAndStoreByScore(K srcKey, K dstKey, Range<Number> range) {
return reverseRangeAndStoreByScore(srcKey, dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with reverse ordering by score from {@literal ZSET} at {@code srcKey} with a score
* between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param srcKey must not be {@literal null}.
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return the number of stored elements or {@literal null} when used in pipeline / transaction.
* @since 3.0
* @see #reverseRangeByScore(Object, double, double, long, long)
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
*/
@Nullable
Long reverseRangeAndStoreByScore(K srcKey, K dstKey, Range<Number> range, Limit limit);
/**
* @return never {@literal null}.

View File

@@ -260,6 +260,30 @@ public class DefaultRedisZSet<E> extends AbstractRedisCollection<E> implements R
return boundZSetOps.reverseRangeWithScores(start, end);
}
@Override
public RedisZSet<E> rangeAndStoreByLex(String dstKey, Range<String> range, Limit limit) {
boundZSetOps.rangeAndStoreByLex(dstKey, range, limit);
return new DefaultRedisZSet<>(getOperations().boundZSetOps(dstKey));
}
@Override
public RedisZSet<E> reverseRangeAndStoreByLex(String dstKey, Range<String> range, Limit limit) {
boundZSetOps.reverseRangeAndStoreByLex(dstKey, range, limit);
return new DefaultRedisZSet<>(getOperations().boundZSetOps(dstKey));
}
@Override
public RedisZSet<E> rangeAndStoreByScore(String dstKey, Range<Number> range, Limit limit) {
boundZSetOps.rangeAndStoreByScore(dstKey, range, limit);
return new DefaultRedisZSet<>(getOperations().boundZSetOps(dstKey));
}
@Override
public RedisZSet<E> reverseRangeAndStoreByScore(String dstKey, Range<Number> range, Limit limit) {
boundZSetOps.reverseRangeAndStoreByScore(dstKey, range, limit);
return new DefaultRedisZSet<>(getOperations().boundZSetOps(dstKey));
}
@Override
public RedisZSet<E> remove(long start, long end) {
boundZSetOps.removeRange(start, end);

View File

@@ -434,6 +434,117 @@ public interface RedisZSet<E> extends RedisCollection<E>, Set<E> {
*/
Set<TypedTuple<E>> reverseRangeByScoreWithScores(double min, double max);
/**
* Store all elements at {@code dstKey} with lexicographical ordering from {@literal ZSET} at the bound key with a
* value between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return a new {@link RedisZSet} pointing at {@code destKey}
* @since 3.0
* @see #rangeByLex(Range)
*/
default RedisZSet<E> rangeAndStoreByLex(String dstKey, Range<String> range) {
return rangeAndStoreByLex(dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with lexicographical ordering from {@literal ZSET} at the bound key with a value between
* {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return a new {@link RedisZSet} pointing at {@code destKey}
* @since 3.0
* @see #rangeByLex(Range, Limit)
*/
RedisZSet<E> rangeAndStoreByLex(String dstKey, Range<String> range, Limit limit);
/**
* Store all elements at {@code dstKey} with reverse lexicographical ordering from {@literal ZSET} at the bound key
* with a value between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return a new {@link RedisZSet} pointing at {@code destKey}
* @since 3.0
* @see #reverseRangeByLex(Range)
*/
default RedisZSet<E> reverseRangeAndStoreByLex(String dstKey, Range<String> range) {
return reverseRangeAndStoreByLex(dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with reverse lexicographical ordering from {@literal ZSET} at the bound key with a value
* between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return a new {@link RedisZSet} pointing at {@code destKey}
* @since 3.0
* @see #reverseRangeByLex(Range, Limit)
*/
RedisZSet<E> reverseRangeAndStoreByLex(String dstKey, Range<String> range, Limit limit);
/**
* Store all elements at {@code dstKey} with ordering by score from {@literal ZSET} at the bound key with a score
* between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return a new {@link RedisZSet} pointing at {@code destKey}
* @since 3.0
* @see #rangeByScore(double, double)
*/
default RedisZSet<E> rangeAndStoreByScore(String dstKey, Range<Number> range) {
return rangeAndStoreByScore(dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with ordering by score from {@literal ZSET} at the bound key with a score between
* {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return a new {@link RedisZSet} pointing at {@code destKey}
* @since 3.0
* @see #rangeByScore(double, double)
*/
RedisZSet<E> rangeAndStoreByScore(String dstKey, Range<Number> range, Limit limit);
/**
* Store all elements at {@code dstKey} with reverse ordering by score from {@literal ZSET} at the bound key with a
* score between {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @return a new {@link RedisZSet} pointing at {@code destKey}
* @since 3.0
* @see #reverseRangeByScore(double, double)
*/
default RedisZSet<E> reverseRangeAndStoreByScore(String dstKey, Range<Number> range) {
return reverseRangeAndStoreByScore(dstKey, range, Limit.unlimited());
}
/**
* Store {@literal n} elements at {@code dstKey}, where {@literal n = } {@link Limit#getCount()}, starting at
* {@link Limit#getOffset()} with reverse ordering by score from {@literal ZSET} at the bound key with a score between
* {@link Range#getLowerBound()} and {@link Range#getUpperBound()}.
*
* @param dstKey must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit must not be {@literal null}.
* @return a new {@link RedisZSet} pointing at {@code destKey}
* @since 3.0
*/
RedisZSet<E> reverseRangeAndStoreByScore(String dstKey, Range<Number> range, Limit limit);
/**
* Remove elements in range between {@code start} and {@code end} from sorted set.
*