/*
* Copyright 2016-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.redis.connection;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.reactivestreams.Publisher;
import org.springframework.data.domain.Range;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.redis.connection.ReactiveRedisConnection.CommandResponse;
import org.springframework.data.redis.connection.ReactiveRedisConnection.KeyCommand;
import org.springframework.data.redis.connection.ReactiveRedisConnection.NumericResponse;
import org.springframework.data.redis.connection.RedisZSetCommands.Aggregate;
import org.springframework.data.redis.connection.RedisZSetCommands.Limit;
import org.springframework.data.redis.connection.RedisZSetCommands.Tuple;
import org.springframework.data.redis.util.ByteUtils;
import org.springframework.util.Assert;
/**
* Redis Sorted Set commands executed using reactive infrastructure.
*
* @author Christoph Strobl
* @author Mark Paluch
* @since 2.0
*/
public interface ReactiveZSetCommands {
/**
* {@code ZADD} command parameters.
*
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/zadd">Redis Documentation: ZADD</a>
*/
class ZAddCommand extends KeyCommand {
private final List<Tuple> tuples;
private final boolean upsert;
private final boolean returnTotalChanged;
private final boolean incr;
private ZAddCommand(ByteBuffer key, List<Tuple> tuples, boolean upsert, boolean returnTotalChanged, boolean incr) {
super(key);
this.tuples = tuples;
this.upsert = upsert;
this.returnTotalChanged = returnTotalChanged;
this.incr = incr;
}
/**
* Creates a new {@link ZAddCommand} given a {@link Tuple}.
*
* @param tuple must not be {@literal null}.
* @return a new {@link ZAddCommand} for {@link Tuple}.
*/
public static ZAddCommand tuple(Tuple tuple) {
Assert.notNull(tuple, "Tuple must not be null!");
return tuples(Collections.singletonList(tuple));
}
/**
* Creates a new {@link ZAddCommand} given a {@link Collection} of {@link Tuple}.
*
* @param tuples must not be {@literal null}.
* @return a new {@link ZAddCommand} for {@link Tuple}.
*/
public static ZAddCommand tuples(Collection<? extends Tuple> tuples) {
Assert.notNull(tuples, "Tuples must not be null!");
return new ZAddCommand(null, new ArrayList<>(tuples), false, false, false);
}
/**
* 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 ZAddCommand} with {@literal key} applied.
*/
public ZAddCommand to(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new ZAddCommand(key, tuples, upsert, returnTotalChanged, incr);
}
/**
* Applies {@literal xx} mode (Only update elements that already exist. Never add elements). Constructs a new
* command instance with all previously configured properties.
*
* @return a new {@link ZAddCommand} with {@literal xx} applied.
*/
public ZAddCommand xx() {
return new ZAddCommand(getKey(), tuples, false, returnTotalChanged, incr);
}
/**
* Applies {@literal nx} mode (Don't update already existing elements. Always add new elements). Constructs a new
* command instance with all previously configured properties.
*
* @return a new {@link ZAddCommand} with {@literal nx} applied.
*/
public ZAddCommand nx() {
return new ZAddCommand(getKey(), tuples, true, returnTotalChanged, incr);
}
/**
* Applies {@literal ch} mode (Modify the return value from the number of new elements added, to the total number of
* elements changed). Constructs a new command instance with all previously configured properties.
*
* @return a new {@link ZAddCommand} with {@literal ch} applied.
*/
public ZAddCommand ch() {
return new ZAddCommand(getKey(), tuples, upsert, true, incr);
}
/**
* Applies {@literal incr} mode (When this option is specified ZADD acts like ZINCRBY). Constructs a new command
* instance with all previously configured properties.
*
* @return a new {@link ZAddCommand} with {@literal incr} applied.
*/
public ZAddCommand incr() {
return new ZAddCommand(getKey(), tuples, upsert, upsert, true);
}
/**
* @return
*/
public List<Tuple> getTuples() {
return tuples;
}
/**
* @return
*/
public boolean isUpsert() {
return upsert;
}
/**
* @return
*/
public boolean isIncr() {
return incr;
}
/**
* @return
*/
public boolean isReturnTotalChanged() {
return returnTotalChanged;
}
}
/**
* Add {@literal value} to a sorted set at {@literal key}, or update its {@literal score} if it already exists.
*
* @param key must not be {@literal null}.
* @param score must not be {@literal null}.
* @param value must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zadd">Redis Documentation: ZADD</a>
*/
default Mono<Long> zAdd(ByteBuffer key, Double score, ByteBuffer value) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(score, "Score must not be null!");
Assert.notNull(value, "Value must not be null!");
return zAdd(Mono.just(ZAddCommand.tuple(new DefaultTuple(ByteUtils.getBytes(value), score)).to(key))).next()
.map(resp -> resp.getOutput().longValue());
}
/**
* Add a {@literal tuples} to a sorted set at {@literal key}, or update their score if it already exists.
*
* @param key must not be {@literal null}.
* @param tuples must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zadd">Redis Documentation: ZADD</a>
*/
default Mono<Long> zAdd(ByteBuffer key, Collection<? extends Tuple> tuples) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(tuples, "Tuples must not be null!");
return zAdd(Mono.just(ZAddCommand.tuples(tuples).to(key))).next().map(resp -> resp.getOutput().longValue());
}
/**
* Add {@link ZAddCommand#getTuples()} to a sorted set at {@link ZAddCommand#getKey()}, or update its {@literal score}
* if it already exists.
*
* @param commands must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zadd">Redis Documentation: ZADD</a>
*/
Flux<NumericResponse<ZAddCommand, Number>> zAdd(Publisher<ZAddCommand> commands);
/**
* {@code ZREM} command parameters.
*
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/zrem">Redis Documentation: ZREM</a>
*/
class ZRemCommand extends KeyCommand {
private final List<ByteBuffer> values;
private ZRemCommand(ByteBuffer key, List<ByteBuffer> values) {
super(key);
this.values = values;
}
/**
* Creates a new {@link ZRemCommand} given a {@link Tuple}.
*
* @param value must not be {@literal null}.
* @return a new {@link ZAddCommand} for {@link Tuple}.
*/
public static ZRemCommand values(ByteBuffer value) {
Assert.notNull(value, "Value must not be null!");
return new ZRemCommand(null, Collections.singletonList(value));
}
/**
* Creates a new {@link ZRemCommand} given a {@link Collection} of {@link Tuple}.
*
* @param values must not be {@literal null}.
* @return a new {@link ZAddCommand} for {@link Tuple}.
*/
public static ZRemCommand values(Collection<ByteBuffer> values) {
Assert.notNull(values, "Values must not be null!");
return new ZRemCommand(null, new ArrayList<>(values));
}
/**
* 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 ZRemCommand} with {@literal key} applied.
*/
public ZRemCommand from(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new ZRemCommand(key, values);
}
/**
* @return
*/
public List<ByteBuffer> getValues() {
return values;
}
}
/**
* Remove {@literal value} from sorted set. Return number of removed elements.
*
* @param key must not be {@literal null}.
* @param value must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrem">Redis Documentation: ZREM</a>
*/
default Mono<Long> zRem(ByteBuffer key, ByteBuffer value) {
Assert.notNull(value, "Value must not be null!");
return zRem(key, Collections.singletonList(value));
}
/**
* Remove {@literal values} from sorted set. Return number of removed elements.
*
* @param key must not be {@literal null}.
* @param values must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrem">Redis Documentation: ZREM</a>
*/
default Mono<Long> zRem(ByteBuffer key, Collection<ByteBuffer> values) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(values, "Values must not be null!");
return zRem(Mono.just(ZRemCommand.values(values).from(key))).next().map(NumericResponse::getOutput);
}
/**
* Remove {@link ZRemCommand#getValues()} from sorted set. Return number of removed elements.
*
* @param commands must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrem">Redis Documentation: ZREM</a>
*/
Flux<NumericResponse<ZRemCommand, Long>> zRem(Publisher<ZRemCommand> commands);
/**
* {@code ZINCRBY} command parameters.
*
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/zincrby">Redis Documentation: ZINCRBY</a>
*/
class ZIncrByCommand extends KeyCommand {
private final ByteBuffer value;
private final Number increment;
private ZIncrByCommand(ByteBuffer key, ByteBuffer value, Number increment) {
super(key);
this.value = value;
this.increment = increment;
}
/**
* Creates a new {@link ZIncrByCommand} given a {@link ByteBuffer member}.
*
* @param member must not be {@literal null}.
* @return a new {@link ZAddCommand} for {@link Tuple}.
*/
public static ZIncrByCommand scoreOf(ByteBuffer member) {
Assert.notNull(member, "Member must not be null!");
return new ZIncrByCommand(null, member, null);
}
/**
* Applies the numeric {@literal increment}. Constructs a new command instance with all previously configured
* properties.
*
* @param increment must not be {@literal null}.
* @return a new {@link ZIncrByCommand} with {@literal increment} applied.
*/
public ZIncrByCommand by(Number increment) {
Assert.notNull(increment, "Increment must not be null!");
return new ZIncrByCommand(getKey(), value, increment);
}
/**
* 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 ZIncrByCommand} with {@literal key} applied.
*/
public ZIncrByCommand storedWithin(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new ZIncrByCommand(key, value, increment);
}
/**
* @return
*/
public ByteBuffer getValue() {
return value;
}
/**
* @return
*/
public Number getIncrement() {
return increment;
}
}
/**
* Increment the score of element with {@literal value} in sorted set by {@literal increment}.
*
* @param key must not be {@literal null}.
* @param increment must not be {@literal null}.
* @param value must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zincrby">Redis Documentation: ZINCRBY</a>
*/
default Mono<Double> zIncrBy(ByteBuffer key, Number increment, ByteBuffer value) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(increment, "Increment must not be null!");
Assert.notNull(value, "Value must not be null!");
return zIncrBy(Mono.just(ZIncrByCommand.scoreOf(value).by(increment).storedWithin(key))).next()
.map(NumericResponse::getOutput);
}
/**
* Increment the score of element with {@link ZIncrByCommand#getValue()} in sorted set by
* {@link ZIncrByCommand#getIncrement()}.
*
* @param commands must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zincrby">Redis Documentation: ZINCRBY</a>
*/
Flux<NumericResponse<ZIncrByCommand, Double>> zIncrBy(Publisher<ZIncrByCommand> commands);
/**
* {@code ZRANK}/{@literal ZREVRANK} command parameters.
*
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/zrank">Redis Documentation: ZRANK</a>
* @see <a href="http://redis.io/commands/zrevrank">Redis Documentation: ZREVRANK</a>
*/
class ZRankCommand extends KeyCommand {
private final ByteBuffer value;
private final Direction direction;
private ZRankCommand(ByteBuffer key, ByteBuffer value, Direction direction) {
super(key);
this.value = value;
this.direction = direction;
}
/**
* Creates a new {@link ZRankCommand} given a {@link ByteBuffer member} to obtain its rank (ordering low to high).
*
* @param member must not be {@literal null}.
* @return a new {@link ZRankCommand} for {@link Tuple}.
*/
public static ZRankCommand indexOf(ByteBuffer member) {
Assert.notNull(member, "Member must not be null!");
return new ZRankCommand(null, member, Direction.ASC);
}
/**
* Creates a new {@link ZIncrByCommand} given a {@link ByteBuffer member} to obtain its reversed rank (ordering high
* to low).
*
* @param member must not be {@literal null}.
* @return a new {@link ZRankCommand} for {@link Tuple}.
*/
public static ZRankCommand reverseIndexOf(ByteBuffer member) {
Assert.notNull(member, "Member must not be null!");
return new ZRankCommand(null, member, Direction.DESC);
}
/**
* 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 ZRankCommand} with {@literal key} applied.
*/
public ZRankCommand storedWithin(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new ZRankCommand(key, value, direction);
}
/**
* @return
*/
public ByteBuffer getValue() {
return value;
}
/**
* @return
*/
public Direction getDirection() {
return direction;
}
}
/**
* Determine the index of element with {@literal value} in a sorted set.
*
* @param key must not be {@literal null}.
* @param value must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrank">Redis Documentation: ZRANK</a>
*/
default Mono<Long> zRank(ByteBuffer key, ByteBuffer value) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return zRank(Mono.just(ZRankCommand.indexOf(value).storedWithin(key))).next().map(NumericResponse::getOutput);
}
/**
* Determine the index of element with {@literal value} in a sorted set when scored high to low.
*
* @param key must not be {@literal null}.
* @param value must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrevrank">Redis Documentation: ZREVRANK</a>
*/
default Mono<Long> zRevRank(ByteBuffer key, ByteBuffer value) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return zRank(Mono.just(ZRankCommand.reverseIndexOf(value).storedWithin(key))).next()
.map(NumericResponse::getOutput);
}
/**
* Determine the index of element with {@literal value} in a sorted set when scored by
* {@link ZRankCommand#getDirection()}.
*
* @param commands must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrank">Redis Documentation: ZRANK</a>
* @see <a href="http://redis.io/commands/zrevrank">Redis Documentation: ZREVRANK</a>
*/
Flux<NumericResponse<ZRankCommand, Long>> zRank(Publisher<ZRankCommand> commands);
/**
* {@code ZRANGE}/{@literal ZREVRANGE} command parameters.
*
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/zrange">Redis Documentation: ZRANGE</a>
* @see <a href="http://redis.io/commands/zrevrange">Redis Documentation: ZREVRANGE</a>
*/
class ZRangeCommand extends KeyCommand {
private final Range<Long> range;
private final boolean withScores;
private final Direction direction;
private ZRangeCommand(ByteBuffer key, Range<Long> range, Direction direction, boolean withScores) {
super(key);
this.range = range;
this.withScores = withScores;
this.direction = direction;
}
/**
* Creates a new {@link ZRangeCommand} 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 ZRangeCommand valuesWithin(Range<Long> range) {
Assert.notNull(range, "Range must not be null!");
return new ZRangeCommand(null, range, Direction.ASC, false);
}
/**
* Creates a new {@link ZRangeCommand} 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 ZRangeCommand} for {@link Tuple}.
*/
public static ZRangeCommand reverseValuesWithin(Range<Long> range) {
Assert.notNull(range, "Range must not be null!");
return new ZRangeCommand(null, range, Direction.DESC, false);
}
/**
* Return the score along with each returned element. Constructs a new command instance with all previously
* configured properties.
*
* @return a new {@link ZRangeCommand} with score retrieval applied.
*/
public ZRangeCommand withScores() {
return new ZRangeCommand(getKey(), range, direction, true);
}
/**
* 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 ZRangeCommand} with {@literal key} applied.
*/
public ZRangeCommand from(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new ZRangeCommand(key, range, direction, withScores);
}
/**
* @return
*/
public Range<Long> getRange() {
return range;
}
/**
* @return
*/
public boolean isWithScores() {
return withScores;
}
/**
* @return
*/
public Direction getDirection() {
return direction;
}
}
/**
* Get elements in {@literal range} from sorted set.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrange">Redis Documentation: ZRANGE</a>
*/
default Flux<ByteBuffer> zRange(ByteBuffer key, Range<Long> range) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
return zRange(Mono.just(ZRangeCommand.valuesWithin(range).from(key))) //
.flatMap(CommandResponse::getOutput).map(tuple -> ByteBuffer.wrap(tuple.getValue()));
}
/**
* Get set of {@link Tuple}s in {@literal range} from sorted set.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrange">Redis Documentation: ZRANGE</a>
*/
default Flux<Tuple> zRangeWithScores(ByteBuffer key, Range<Long> range) {
Assert.notNull(key, "Key must not be null!");
return zRange(Mono.just(ZRangeCommand.valuesWithin(range).withScores().from(key)))
.flatMap(CommandResponse::getOutput);
}
/**
* Get elements in {@literal range} from sorted set in reverse {@literal score} ordering.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrevrange">Redis Documentation: ZREVRANGE</a>
*/
default Flux<ByteBuffer> zRevRange(ByteBuffer key, Range<Long> range) {
Assert.notNull(key, "Key must not be null!");
return zRange(Mono.just(ZRangeCommand.reverseValuesWithin(range).from(key))).flatMap(CommandResponse::getOutput)
.map(tuple -> ByteBuffer.wrap(tuple.getValue()));
}
/**
* Get set of {@link Tuple}s in {@literal range} from sorted set in reverse {@literal score} ordering.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrevrange">Redis Documentation: ZREVRANGE</a>
*/
default Flux<Tuple> zRevRangeWithScores(ByteBuffer key, Range<Long> range) {
Assert.notNull(key, "Key must not be null!");
return zRange(Mono.just(ZRangeCommand.reverseValuesWithin(range).withScores().from(key)))
.flatMap(CommandResponse::getOutput);
}
/**
* Get set of {@link Tuple}s in {@literal range} from sorted set.
*
* @param commands must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrange">Redis Documentation: ZRANGE</a>
* @see <a href="http://redis.io/commands/zrevrange">Redis Documentation: ZREVRANGE</a>
*/
Flux<CommandResponse<ZRangeCommand, Flux<Tuple>>> zRange(Publisher<ZRangeCommand> commands);
/**
* {@literal ZRANGEBYSCORE}/{@literal ZREVRANGEBYSCORE}.
*
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
class ZRangeByScoreCommand extends KeyCommand {
private final Range<Double> range;
private final boolean withScores;
private final Direction direction;
private final Limit limit;
private ZRangeByScoreCommand(ByteBuffer key, Range<Double> range, Direction direction, boolean withScores,
Limit limit) {
super(key);
this.range = range;
this.withScores = withScores;
this.direction = direction;
this.limit = limit;
}
/**
* Creates a new {@link ZRangeByScoreCommand} 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 ZRangeByScoreCommand} for {@link Tuple}.
*/
public static ZRangeByScoreCommand scoresWithin(Range<Double> range) {
Assert.notNull(range, "Range must not be null!");
return new ZRangeByScoreCommand(null, range, Direction.ASC, false, null);
}
/**
* Creates a new {@link ZRangeByScoreCommand} 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 ZRangeByScoreCommand} for {@link Tuple}.
*/
public static ZRangeByScoreCommand reverseScoresWithin(Range<Double> range) {
Assert.notNull(range, "Range must not be null!");
return new ZRangeByScoreCommand(null, range, Direction.DESC, false, null);
}
/**
* Return the score along with each returned element. Constructs a new command instance with all previously
* configured properties.
*
* @return a new {@link ZRangeByScoreCommand} with score retrieval applied.
*/
public ZRangeByScoreCommand withScores() {
return new ZRangeByScoreCommand(getKey(), range, direction, true, 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 ZRangeByScoreCommand} with {@literal key} applied.
*/
public ZRangeByScoreCommand from(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new ZRangeByScoreCommand(key, range, direction, withScores, limit);
}
/**
* Applies the {@link Limit}. Constructs a new command instance with all previously configured properties.
*
* @param limit can be {@literal null}.
* @return a new {@link ZRangeByScoreCommand} with {@link Limit} applied.
*/
public ZRangeByScoreCommand limitTo(Limit limit) {
return new ZRangeByScoreCommand(getKey(), range, direction, withScores, limit);
}
/**
* @return
*/
public Range<Double> getRange() {
return range;
}
/**
* @return
*/
public boolean isWithScores() {
return withScores;
}
/**
* @return
*/
public Direction getDirection() {
return direction;
}
/**
* @return
*/
public Optional<Limit> getLimit() {
return Optional.ofNullable(limit);
}
}
/**
* Get elements in {@literal range} from sorted set.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
default Flux<ByteBuffer> zRangeByScore(ByteBuffer key, Range<Double> range) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
return zRangeByScore(Mono.just(ZRangeByScoreCommand.scoresWithin(range).from(key))) //
.flatMap(CommandResponse::getOutput) //
.map(tuple -> ByteBuffer.wrap(tuple.getValue()));
}
/**
* Get elements in {@literal range} from sorted set.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit can be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
default Flux<ByteBuffer> zRangeByScore(ByteBuffer key, Range<Double> range, Limit limit) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
return zRangeByScore(Mono.just(ZRangeByScoreCommand.scoresWithin(range).from(key).limitTo(limit))) //
.flatMap(CommandResponse::getOutput) //
.map(tuple -> ByteBuffer.wrap(tuple.getValue()));
}
/**
* Get {@link Tuple}s in {@literal range} from sorted set.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
default Flux<Tuple> zRangeByScoreWithScores(ByteBuffer key, Range<Double> range) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
return zRangeByScore(Mono.just(ZRangeByScoreCommand.scoresWithin(range).withScores().from(key)))
.flatMap(CommandResponse::getOutput);
}
/**
* Get {@link Tuple}s in {@literal range} from sorted set.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit can be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
*/
default Flux<Tuple> zRangeByScoreWithScores(ByteBuffer key, Range<Double> range, Limit limit) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
return zRangeByScore(Mono.just(ZRangeByScoreCommand.scoresWithin(range).withScores().from(key).limitTo(limit)))
.flatMap(CommandResponse::getOutput);
}
/**
* Get elements in {@literal range} from sorted set in reverse {@literal score} ordering.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
default Flux<ByteBuffer> zRevRangeByScore(ByteBuffer key, Range<Double> range) {
Assert.notNull(key, "Key must not be null!");
return zRangeByScore(Mono.just(ZRangeByScoreCommand.reverseScoresWithin(range).from(key))) //
.flatMap(CommandResponse::getOutput) //
.map(tuple -> ByteBuffer.wrap(tuple.getValue()));
}
/**
* Get elements in {@literal range} from sorted set in reverse {@literal score} ordering.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit can be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
default Flux<ByteBuffer> zRevRangeByScore(ByteBuffer key, Range<Double> range, Limit limit) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
return zRangeByScore(Mono.just(ZRangeByScoreCommand.reverseScoresWithin(range).from(key).limitTo(limit))) //
.flatMap(CommandResponse::getOutput) //
.map(tuple -> ByteBuffer.wrap(tuple.getValue()));
}
/**
* Get set of {@link Tuple}s in {@literal range} from sorted set in reverse {@literal score} ordering.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
default Flux<Tuple> zRevRangeByScoreWithScores(ByteBuffer key, Range<Double> range) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
return zRangeByScore(Mono.just(ZRangeByScoreCommand.reverseScoresWithin(range).withScores().from(key)))
.flatMap(CommandResponse::getOutput);
}
/**
* Get {@link Tuple}s in {@literal range} from sorted set in reverse {@literal score} ordering.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit can be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
default Flux<Tuple> zRevRangeByScoreWithScores(ByteBuffer key, Range<Double> range, Limit limit) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
return zRangeByScore(
Mono.just(ZRangeByScoreCommand.reverseScoresWithin(range).withScores().from(key).limitTo(limit)))
.flatMap(CommandResponse::getOutput);
}
/**
* Get {@link Tuple}s in {@literal range} from sorted set.
*
* @param commands must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrangebyscore">Redis Documentation: ZRANGEBYSCORE</a>
* @see <a href="http://redis.io/commands/zrevrangebyscore">Redis Documentation: ZREVRANGEBYSCORE</a>
*/
Flux<CommandResponse<ZRangeByScoreCommand, Flux<Tuple>>> zRangeByScore(Publisher<ZRangeByScoreCommand> commands);
/**
* {@code ZCOUNT} command parameters.
*
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/zcount">Redis Documentation: ZCOUNT</a>
*/
class ZCountCommand extends KeyCommand {
private final Range<Double> range;
private ZCountCommand(ByteBuffer key, Range<Double> range) {
super(key);
this.range = range;
}
/**
* Creates a new {@link ZCountCommand} given a {@link Range}.
*
* @param range must not be {@literal null}.
* @return a new {@link ZCountCommand} for {@link Range}.
*/
public static ZCountCommand scoresWithin(Range<Double> range) {
Assert.notNull(range, "Range must not be null!");
return new ZCountCommand(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 ZCountCommand} with {@literal key} applied.
*/
public ZCountCommand forKey(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new ZCountCommand(key, range);
}
/**
* @return
*/
public Range<Double> getRange() {
return range;
}
}
/**
* Count number of elements within sorted set with scores within {@link Range}. <br />
* <b>NOTE</b> please use {@link Double#NEGATIVE_INFINITY} for {@literal -inf} and {@link Double#POSITIVE_INFINITY}
* for {@literal +inf}.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zcount">Redis Documentation: ZCOUNT</a>
*/
default Mono<Long> zCount(ByteBuffer key, Range<Double> range) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
return zCount(Mono.just(ZCountCommand.scoresWithin(range).forKey(key))).next().map(NumericResponse::getOutput);
}
/**
* Count number of elements within sorted set with scores within {@link Range}. <br />
* <b>NOTE</b> please use {@link Double#NEGATIVE_INFINITY} for {@literal -inf} and {@link Double#POSITIVE_INFINITY}
* for {@literal +inf}.
*
* @param commands must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zcount">Redis Documentation: ZCOUNT</a>
*/
Flux<NumericResponse<ZCountCommand, Long>> zCount(Publisher<ZCountCommand> commands);
/**
* Get the size of sorted set with {@literal key}.
*
* @param key must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zcard">Redis Documentation: ZCARD</a>
*/
default Mono<Long> zCard(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return zCard(Mono.just(new KeyCommand(key))).next().map(NumericResponse::getOutput);
}
/**
* Get the size of sorted set with {@link KeyCommand#getKey()}.
*
* @param commands must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zcard">Redis Documentation: ZCARD</a>
*/
Flux<NumericResponse<KeyCommand, Long>> zCard(Publisher<KeyCommand> commands);
/**
* {@code ZSCORE} command parameters.
*
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/zscore">Redis Documentation: ZSCORE</a>
*/
class ZScoreCommand extends KeyCommand {
private final ByteBuffer value;
private ZScoreCommand(ByteBuffer key, ByteBuffer value) {
super(key);
this.value = value;
}
/**
* Creates a new {@link ZScoreCommand} given a {@link ByteBuffer member}.
*
* @param member must not be {@literal null}.
* @return a new {@link ZScoreCommand} for {@link Range}.
*/
public static ZScoreCommand scoreOf(ByteBuffer member) {
Assert.notNull(member, "Member must not be null!");
return new ZScoreCommand(null, member);
}
/**
* 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 ZScoreCommand} with {@literal key} applied.
*/
public ZScoreCommand forKey(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new ZScoreCommand(key, value);
}
/**
* @return
*/
public ByteBuffer getValue() {
return value;
}
}
/**
* Get the score of element with {@literal value} from sorted set with key {@literal key}.
*
* @param key must not be {@literal null}.
* @param value must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zscore">Redis Documentation: ZSCORE</a>
*/
default Mono<Double> zScore(ByteBuffer key, ByteBuffer value) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(value, "Value must not be null!");
return zScore(Mono.just(ZScoreCommand.scoreOf(value).forKey(key))).next().map(NumericResponse::getOutput);
}
/**
* Get the score of element with {@link ZScoreCommand#getValue()} from sorted set with key
* {@link ZScoreCommand#getKey()}
*
* @param commands must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zscore">Redis Documentation: ZSCORE</a>
*/
Flux<NumericResponse<ZScoreCommand, Double>> zScore(Publisher<ZScoreCommand> commands);
/**
* {@code ZREMRANGEBYRANK} command parameters.
*
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/zremrangebyrank">Redis Documentation: ZREMRANGEBYRANK</a>
*/
class ZRemRangeByRankCommand extends KeyCommand {
private final Range<Long> range;
private ZRemRangeByRankCommand(ByteBuffer key, Range<Long> range) {
super(key);
this.range = range;
}
/**
* Creates a new {@link ZRemRangeByRankCommand} given a {@link Range}.
*
* @param range must not be {@literal null}.
* @return a new {@link ZRemRangeByRankCommand} for {@link Range}.
*/
public static ZRemRangeByRankCommand valuesWithin(Range<Long> range) {
Assert.notNull(range, "Range must not be null!");
return new ZRemRangeByRankCommand(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 ZRemRangeByRankCommand} with {@literal key} applied.
*/
public ZRemRangeByRankCommand from(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new ZRemRangeByRankCommand(key, range);
}
/**
* @return
*/
public Range<Long> getRange() {
return range;
}
}
/**
* Remove elements in {@link Range} from sorted set with {@literal key}.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zremrangebyrank">Redis Documentation: ZREMRANGEBYRANK</a>
*/
default Mono<Long> zRemRangeByRank(ByteBuffer key, Range<Long> range) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
return zRemRangeByRank(Mono.just(ZRemRangeByRankCommand.valuesWithin(range).from(key))).next()
.map(NumericResponse::getOutput);
}
/**
* Remove elements in {@link Range} from sorted set with {@link ZRemRangeByRankCommand#getKey()}.
*
* @param commands must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zremrangebyrank">Redis Documentation: ZREMRANGEBYRANK</a>
*/
Flux<NumericResponse<ZRemRangeByRankCommand, Long>> zRemRangeByRank(Publisher<ZRemRangeByRankCommand> commands);
/**
* {@code ZREMRANGEBYSCORE} command parameters.
*
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/zremrangebyscore">Redis Documentation: ZREMRANGEBYSCORE</a>
*/
class ZRemRangeByScoreCommand extends KeyCommand {
private final Range<Double> range;
private ZRemRangeByScoreCommand(ByteBuffer key, Range<Double> range) {
super(key);
this.range = range;
}
/**
* Creates a new {@link ZRemRangeByScoreCommand} given a {@link Range}.
*
* @param range must not be {@literal null}.
* @return a new {@link ZRemRangeByScoreCommand} for {@link Range}.
*/
public static ZRemRangeByScoreCommand scoresWithin(Range<Double> range) {
return new ZRemRangeByScoreCommand(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 ZRemRangeByRankCommand} with {@literal key} applied.
*/
public ZRemRangeByScoreCommand from(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new ZRemRangeByScoreCommand(key, range);
}
/**
* @return
*/
public Range<Double> getRange() {
return range;
}
}
/**
* Remove elements in {@link Range} from sorted set with {@literal key}.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zremrangebyscore">Redis Documentation: ZREMRANGEBYSCORE</a>
*/
default Mono<Long> zRemRangeByScore(ByteBuffer key, Range<Double> range) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
return zRemRangeByScore(Mono.just(ZRemRangeByScoreCommand.scoresWithin(range).from(key))).next()
.map(NumericResponse::getOutput);
}
/**
* Remove elements in {@link Range} from sorted set with {@link ZRemRangeByRankCommand#getKey()}.
*
* @param commands must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zremrangebyscore">Redis Documentation: ZREMRANGEBYSCORE</a>
*/
Flux<NumericResponse<ZRemRangeByScoreCommand, Long>> zRemRangeByScore(Publisher<ZRemRangeByScoreCommand> commands);
/**
* {@code ZUNIONSTORE} command parameters.
*
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/zunionstore">Redis Documentation: ZUNIONSTORE</a>
*/
class ZUnionStoreCommand extends KeyCommand {
private final List<ByteBuffer> sourceKeys;
private final List<Double> weights;
private final Aggregate aggregateFunction;
private ZUnionStoreCommand(ByteBuffer key, List<ByteBuffer> sourceKeys, List<Double> weights, Aggregate aggregate) {
super(key);
this.sourceKeys = sourceKeys;
this.weights = weights;
this.aggregateFunction = aggregate;
}
/**
* Creates a new {@link ZUnionStoreCommand} given a {@link List} of keys.
*
* @param keys must not be {@literal null}.
* @return a new {@link ZUnionStoreCommand} for {@link Range}.
*/
public static ZUnionStoreCommand sets(List<ByteBuffer> keys) {
Assert.notNull(keys, "Keys must not be null!");
return new ZUnionStoreCommand(null, new ArrayList<>(keys), null, null);
}
/**
* Applies the {@link List} of weights. Constructs a new command instance with all previously configured properties.
*
* @param weights must not be {@literal null}.
* @return a new {@link ZUnionStoreCommand} with {@literal weights} applied.
*/
public ZUnionStoreCommand applyWeights(List<Double> weights) {
return new ZUnionStoreCommand(getKey(), sourceKeys, weights, aggregateFunction);
}
/**
* Applies a specific {@link Aggregate} function. Constructs a new command instance with all previously configured
* properties.
*
* @param aggregateFunction can be {@literal null}.
* @return a new {@link ZUnionStoreCommand} with {@link Aggregate} applied.
*/
public ZUnionStoreCommand aggregateUsing(Aggregate aggregateFunction) {
return new ZUnionStoreCommand(getKey(), sourceKeys, weights, aggregateFunction);
}
/**
* Applies the {@literal key} at which the result is stored. Constructs a new command instance with all previously
* configured properties.
*
* @param key must not be {@literal null}.
* @return a new {@link ZUnionStoreCommand} with {@literal key} applied.
*/
public ZUnionStoreCommand storeAs(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new ZUnionStoreCommand(key, sourceKeys, weights, aggregateFunction);
}
/**
* @return
*/
public List<ByteBuffer> getSourceKeys() {
return sourceKeys;
}
/**
* @return
*/
public List<Double> getWeights() {
return weights == null ? Collections.emptyList() : weights;
}
/**
* @return
*/
public Optional<Aggregate> getAggregateFunction() {
return Optional.ofNullable(aggregateFunction);
}
}
/**
* Union sorted {@literal sets} and store result in destination {@literal destinationKey}.
*
* @param destinationKey must not be {@literal null}.
* @param sets must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zunionstore">Redis Documentation: ZUNIONSTORE</a>
*/
default Mono<Long> zUnionStore(ByteBuffer destinationKey, List<ByteBuffer> sets) {
return zUnionStore(destinationKey, sets, null);
}
/**
* Union sorted {@literal sets} and store result in destination {@literal destinationKey} and apply weights to
* individual sets.
*
* @param destinationKey must not be {@literal null}.
* @param sets must not be {@literal null}.
* @param weights can be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zunionstore">Redis Documentation: ZUNIONSTORE</a>
*/
default Mono<Long> zUnionStore(ByteBuffer destinationKey, List<ByteBuffer> sets, List<Double> weights) {
return zUnionStore(destinationKey, sets, weights, null);
}
/**
* Union sorted {@literal sets} by applying {@literal aggregateFunction} and store result in destination
* {@literal destinationKey} and apply weights to individual sets.
*
* @param destinationKey must not be {@literal null}.
* @param sets must not be {@literal null}.
* @param weights can be {@literal null}.
* @param aggregateFunction can be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zunionstore">Redis Documentation: ZUNIONSTORE</a>
*/
default Mono<Long> zUnionStore(ByteBuffer destinationKey, List<ByteBuffer> sets, List<Double> weights,
Aggregate aggregateFunction) {
Assert.notNull(destinationKey, "DestinationKey must not be null!");
Assert.notNull(sets, "Sets must not be null!");
return zUnionStore(Mono.just(
ZUnionStoreCommand.sets(sets).aggregateUsing(aggregateFunction).applyWeights(weights).storeAs(destinationKey)))
.next().map(NumericResponse::getOutput);
}
/**
* Union sorted {@literal sets} by applying {@literal aggregateFunction} and store result in destination
* {@literal destinationKey} and apply weights to individual sets.
*
* @param commands
* @return
* @see <a href="http://redis.io/commands/zunionstore">Redis Documentation: ZUNIONSTORE</a>
*/
Flux<NumericResponse<ZUnionStoreCommand, Long>> zUnionStore(Publisher<ZUnionStoreCommand> commands);
/**
* {@code ZINTERSTORE} command parameters.
*
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/zinterstore">Redis Documentation: ZINTERSTORE</a>
*/
class ZInterStoreCommand extends KeyCommand {
private final List<ByteBuffer> sourceKeys;
private final List<Double> weights;
private final Aggregate aggregateFunction;
private ZInterStoreCommand(ByteBuffer key, List<ByteBuffer> sourceKeys, List<Double> weights, Aggregate aggregate) {
super(key);
this.sourceKeys = sourceKeys;
this.weights = weights;
this.aggregateFunction = aggregate;
}
/**
* Creates a new {@link ZInterStoreCommand} given a {@link List} of keys.
*
* @param keys must not be {@literal null}.
* @return a new {@link ZInterStoreCommand} for {@link Range}.
*/
public static ZInterStoreCommand sets(List<ByteBuffer> keys) {
Assert.notNull(keys, "Keys must not be null!");
return new ZInterStoreCommand(null, new ArrayList<>(keys), null, null);
}
/**
* Applies the {@link Collection} of weights. Constructs a new command instance with all previously configured
* properties.
*
* @param weights must not be {@literal null}.
* @return a new {@link ZInterStoreCommand} with {@literal weights} applied.
*/
public ZInterStoreCommand applyWeights(List<Double> weights) {
return new ZInterStoreCommand(getKey(), sourceKeys, weights, aggregateFunction);
}
/**
* Applies a specific {@link Aggregate} function. Constructs a new command instance with all previously configured
* properties.
*
* @param aggregateFunction can be {@literal null}.
* @return a new {@link ZInterStoreCommand} with {@link Aggregate} applied.
*/
public ZInterStoreCommand aggregateUsing(Aggregate aggregateFunction) {
return new ZInterStoreCommand(getKey(), sourceKeys, weights, aggregateFunction);
}
/**
* Applies the {@literal key} at which the result is stored. Constructs a new command instance with all previously
* configured properties.
*
* @param key must not be {@literal null}.
* @return a new {@link ZInterStoreCommand} with {@literal key} applied.
*/
public ZInterStoreCommand storeAs(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new ZInterStoreCommand(key, sourceKeys, weights, aggregateFunction);
}
/**
* @return
*/
public List<ByteBuffer> getSourceKeys() {
return sourceKeys;
}
/**
* @return
*/
public List<Double> getWeights() {
return weights == null ? Collections.emptyList() : weights;
}
/**
* @return
*/
public Optional<Aggregate> getAggregateFunction() {
return Optional.ofNullable(aggregateFunction);
}
}
/**
* Intersect sorted {@literal sets} and store result in destination {@literal destinationKey}.
*
* @param destinationKey must not be {@literal null}.
* @param sets must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zinterstore">Redis Documentation: ZINTERSTORE</a>
*/
default Mono<Long> zInterStore(ByteBuffer destinationKey, List<ByteBuffer> sets) {
return zInterStore(destinationKey, sets, null);
}
/**
* Intersect sorted {@literal sets} and store result in destination {@literal destinationKey} and apply weights to
* individual sets.
*
* @param destinationKey must not be {@literal null}.
* @param sets must not be {@literal null}.
* @param weights can be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zinterstore">Redis Documentation: ZINTERSTORE</a>
*/
default Mono<Long> zInterStore(ByteBuffer destinationKey, List<ByteBuffer> sets, List<Double> weights) {
return zInterStore(destinationKey, sets, weights, null);
}
/**
* Intersect sorted {@literal sets} by applying {@literal aggregateFunction} and store result in destination
* {@literal destinationKey} and apply weights to individual sets.
*
* @param destinationKey must not be {@literal null}.
* @param sets must not be {@literal null}.
* @param weights can be {@literal null}.
* @param aggregateFunction can be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zinterstore">Redis Documentation: ZINTERSTORE</a>
*/
default Mono<Long> zInterStore(ByteBuffer destinationKey, List<ByteBuffer> sets, List<Double> weights,
Aggregate aggregateFunction) {
Assert.notNull(destinationKey, "DestinationKey must not be null!");
Assert.notNull(sets, "Sets must not be null!");
return zInterStore(Mono.just(
ZInterStoreCommand.sets(sets).aggregateUsing(aggregateFunction).applyWeights(weights).storeAs(destinationKey)))
.next().map(NumericResponse::getOutput);
}
/**
* Intersect sorted {@literal sets} by applying {@literal aggregateFunction} and store result in destination
* {@literal destinationKey} and apply weights to individual sets.
*
* @param commands
* @return
* @see <a href="http://redis.io/commands/zinterstore">Redis Documentation: ZINTERSTORE</a>
*/
Flux<NumericResponse<ZInterStoreCommand, Long>> zInterStore(Publisher<ZInterStoreCommand> commands);
/**
* {@code ZRANGEBYLEX}/{@literal ZREVRANGEBYLEX} command parameters.
*
* @author Christoph Strobl
* @see <a href="http://redis.io/commands/zrangebylex">Redis Documentation: ZRANGEBYLEX</a>
* @see <a href="http://redis.io/commands/zrevrangebylex">Redis Documentation: ZREVRANGEBYLEX</a>
*/
class ZRangeByLexCommand extends KeyCommand {
private final Range<String> range;
private final Direction direction;
private final Limit limit;
private ZRangeByLexCommand(ByteBuffer key, Range<String> range, Direction direction, Limit limit) {
super(key);
this.range = range;
this.direction = direction;
this.limit = limit;
}
/**
* Creates a new {@link ZRangeByLexCommand} given a {@link Range} of {@link String} to retrieve elements
* lexicographical ordering.
*
* @param range must not be {@literal null}.
* @return a new {@link ZRangeByLexCommand} for {@link Tuple}.
*/
public static ZRangeByLexCommand stringsWithin(Range<String> range) {
Assert.notNull(range, "Range must not be null!");
return new ZRangeByLexCommand(null, range, Direction.ASC, null);
}
/**
* Creates a new {@link ZRangeByLexCommand} given a {@link Range} of {@link String} to obtain elements in reverse
* lexicographical ordering.
*
* @param range must not be {@literal null}.
* @return a new {@link ZRangeByLexCommand} for {@link Tuple}.
*/
public static ZRangeByLexCommand reverseStringsWithin(Range<String> range) {
Assert.notNull(range, "Range must not be null!");
return new ZRangeByLexCommand(null, range, Direction.DESC, null);
}
/**
* 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 ZRangeByLexCommand} with {@literal key} applied.
*/
public ZRangeByLexCommand from(ByteBuffer key) {
Assert.notNull(key, "Key must not be null!");
return new ZRangeByLexCommand(key, range, direction, limit);
}
/**
* Applies the {@link Limit}. Constructs a new command instance with all previously configured properties.
*
* @param limit can be {@literal null}.
* @return a new {@link ZRangeByLexCommand} with {@link Limit} applied.
*/
public ZRangeByLexCommand limitTo(Limit limit) {
return new ZRangeByLexCommand(getKey(), range, direction, limit);
}
/**
* @return
*/
public Range<String> getRange() {
return range;
}
/**
* @return
*/
public Limit getLimit() {
return limit;
}
/**
* @return
*/
public Direction getDirection() {
return direction;
}
}
/**
* Get all elements in {@link Range} from the sorted set at {@literal key} in lexicographical ordering.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrangebylex">Redis Documentation: ZRANGEBYLEX</a>
*/
default Flux<ByteBuffer> zRangeByLex(ByteBuffer key, Range<String> range) {
return zRangeByLex(key, range, null);
}
/**
* Get all elements in {@link Range} from the sorted set at {@literal key} in lexicographical ordering. Result is
* limited via {@link Limit}.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit can be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrangebylex">Redis Documentation: ZRANGEBYLEX</a>
*/
default Flux<ByteBuffer> zRangeByLex(ByteBuffer key, Range<String> range, Limit limit) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
return zRangeByLex(Mono.just(ZRangeByLexCommand.stringsWithin(range).from(key).limitTo(limit)))
.flatMap(CommandResponse::getOutput);
}
/**
* Get all elements in {@link Range} from the sorted set at {@literal key} in lexicographical ordering.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrevrangebylex">Redis Documentation: ZREVRANGEBYLEX</a>
*/
default Flux<ByteBuffer> zRevRangeByLex(ByteBuffer key, Range<String> range) {
return zRevRangeByLex(key, range, null);
}
/**
* Get all elements in {@link Range} from the sorted set at {@literal key} in lexicographical ordering. Result is
* limited via {@link Limit}.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @param limit can be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrevrangebylex">Redis Documentation: ZREVRANGEBYLEX</a>
*/
default Flux<ByteBuffer> zRevRangeByLex(ByteBuffer key, Range<String> range, Limit limit) {
Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");
return zRangeByLex(Mono.just(ZRangeByLexCommand.reverseStringsWithin(range).from(key).limitTo(limit)))
.flatMap(CommandResponse::getOutput);
}
/**
* Get all elements in {@link Range} from the sorted set at {@literal key} in lexicographical ordering. Result is
* limited via {@link Limit} and sorted by {@link ZRangeByLexCommand#getDirection()}.
*
* @param commands must not be {@literal null}.
* @return
* @see <a href="http://redis.io/commands/zrangebylex">Redis Documentation: ZRANGEBYLEX</a>
* @see <a href="http://redis.io/commands/zrevrangebylex">Redis Documentation: ZREVRANGEBYLEX</a>
*/
Flux<CommandResponse<ZRangeByLexCommand, Flux<ByteBuffer>>> zRangeByLex(Publisher<ZRangeByLexCommand> commands);
}