Skip to content

Add support for ZREMRANGEBYLEX command. #1968

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.5.0-SNAPSHOT</version>
<version>2.5.0-GH-1816-SNAPSHOT</version>

<name>Spring Data Redis</name>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1581,6 +1581,15 @@ public Long zRemRange(byte[] key, long start, long end) {
return convertAndReturn(delegate.zRemRange(key, start, end), Converters.identityConverter());
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRangeByLex(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Long zRemRangeByLex(byte[] key, Range range) {
return convertAndReturn(delegate.zRemRangeByLex(key, range), Converters.identityConverter());
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRangeByScore(byte[], double, double)
Expand Down Expand Up @@ -2829,6 +2838,15 @@ public Long zRemRange(String key, long start, long end) {
return zRemRange(serialize(key), start, end);
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.StringRedisConnection#zRemRange(java.lang.String, org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Long zRemRangeByLex(String key, Range range) {
return zRemRangeByLex(serialize(key), range);
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.StringRedisConnection#zRemRangeByScore(java.lang.String, double, double)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,13 @@ default Long zRemRange(byte[] key, long start, long end) {
return zSetCommands().zRemRange(key, start, end);
}

/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
@Override
@Deprecated
default Long zRemRangeByLex(byte[] key, Range range) {
return zSetCommands().zRemRangeByLex(key, range);
}

/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
@Override
@Deprecated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1444,6 +1444,82 @@ default Mono<Long> zRemRangeByScore(ByteBuffer key, Range<Double> range) {
*/
Flux<NumericResponse<ZRemRangeByScoreCommand, Long>> zRemRangeByScore(Publisher<ZRemRangeByScoreCommand> commands);

/**
* {@code ZREMRANGEBYLEX} command parameters.
*
* @author Christoph Strobl
* @since 2.5
* @see <a href="https://redis.io/commands/zremrangebylex">Redis Documentation: ZREMRANGEBYLEX</a>
*/
class ZRemRangeByLexCommand extends KeyCommand {

private final Range<String> range;

private ZRemRangeByLexCommand(@Nullable ByteBuffer key, Range<String> range) {

super(key);
this.range = range;
}

/**
* Creates a new {@link ZRemRangeByLexCommand} given a {@link Range}.
*
* @param range must not be {@literal null}.
* @return a new {@link ZRemRangeByScoreCommand} for {@link Range}.
*/
public static ZRemRangeByLexCommand lexWithin(Range<String> range) {
return new ZRemRangeByLexCommand(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 ZRemRangeByLexCommand} with {@literal key} applied.
*/
public ZRemRangeByLexCommand from(ByteBuffer key) {

Assert.notNull(key, "Key must not be null!");

return new ZRemRangeByLexCommand(key, range);
}

/**
* @return
*/
public Range<String> 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 a {@link Mono} emitting the number of removed elements.
* @since 2.5
* @see <a href="https://redis.io/commands/zremrangebylex">Redis Documentation: ZREMRANGEBYLEX</a>
*/
default Mono<Long> zRemRangeByLex(ByteBuffer key, Range<String> range) {

Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");

return zRemRangeByLex(Mono.just(ZRemRangeByLexCommand.lexWithin(range).from(key))).next()
.map(NumericResponse::getOutput);
}

/**
* Remove elements in {@link Range} from sorted set with {@link ZRemRangeByLexCommand#getKey()}.
*
* @param commands must not be {@literal null}.
* @return
* @since 2.5
* @see <a href="https://redis.io/commands/zremrangebylex">Redis Documentation: ZREMRANGEBYLEX</a>
*/
Flux<NumericResponse<ZRemRangeByLexCommand, Long>> zRemRangeByLex(Publisher<ZRemRangeByLexCommand> commands);

/**
* {@code ZUNIONSTORE} command parameters.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,17 @@ default Long zCount(byte[] key, double min, double max) {
@Nullable
Long zRemRange(byte[] key, long start, long end);

/**
* Remove all elements between the lexicographical {@link Range}.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of elements removed, or {@literal null} when used in pipeline / transaction.
* @since 2.5
* @see <a href="https://redis.io/commands/zremrangebylex">Redis Documentation: ZREMRANGEBYLEX</a>
*/
Long zRemRangeByLex(byte[] key, Range range);

/**
* Remove elements with scores between {@code min} and {@code max} from sorted set with {@code key}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,18 @@ default Long lPos(String key, String element) {
*/
Long zRemRange(String key, long start, long end);


/**
* Remove all elements between the lexicographical {@link Range}.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return the number of elements removed, or {@literal null} when used in pipeline / transaction.
* @since 2.5
* @see <a href="https://redis.io/commands/zremrangebylex">Redis Documentation: ZREMRANGEBYLEX</a>
*/
Long zRemRangeByLex(String key, Range range);

/**
* Remove elements with scores between {@code min} and {@code max} from sorted set with {@code key}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
package org.springframework.data.redis.connection.convert;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;
Expand All @@ -24,7 +23,7 @@
import org.springframework.util.Assert;

/**
* Converts a Set of values of one type to a Set of values of another type
* Converts a Set of values of one type to a Set of values of another type preserving item order.
*
* @author Jennifer Hickey
* @author Christoph Strobl
Expand All @@ -50,9 +49,7 @@ public SetConverter(Converter<S, T> itemConverter) {
*/
@Override
public Set<T> convert(Set<S> source) {

return source.stream().map(itemConverter::convert)
.collect(Collectors.toCollection(source instanceof LinkedHashSet ? LinkedHashSet::new : HashSet::new));
return source.stream().map(itemConverter::convert).collect(Collectors.toCollection(LinkedHashSet::new));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,26 @@ public Set<byte[]> zRangeByLex(byte[] key, Range range, Limit limit) {
}
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRangeByLex(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Long zRemRangeByLex(byte[] key, Range range) {

Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null for ZREMRANGEBYLEX!");

byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES);

try {
return connection.getCluster().zremrangeByLex(key, min, max);
} catch (Exception ex) {
throw convertJedisAccessException(ex);
}
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByLex(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,22 @@ public Long zRemRange(byte[] key, long start, long end) {
end);
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRangeByLex(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Long zRemRangeByLex(byte[] key, Range range) {

Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null for ZREMRANGEBYLEX!");

byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES);
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES);

return connection.invoke().just(BinaryJedis::zremrangeByLex, MultiKeyPipelineBase::zremrangeByLex, key, min, max);
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,24 @@ public Flux<NumericResponse<ZRemRangeByScoreCommand, Long>> zRemRangeByScore(
}));
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.ReactiveZSetCommands#zRemRangeByLex(org.reactivestreams.Publisher)
*/
@Override
public Flux<NumericResponse<ZRemRangeByLexCommand, Long>> zRemRangeByLex(Publisher<ZRemRangeByLexCommand> commands) {

return connection.execute(cmd -> Flux.from(commands).concatMap(command -> {

Assert.notNull(command.getKey(), "Key must not be null!");
Assert.notNull(command.getRange(), "Range must not be null!");

Mono<Long> result = cmd.zremrangebylex(command.getKey(), RangeConverter.toRange(command.getRange()));

return result.map(value -> new NumericResponse<>(command, value));
}));
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.ReactiveZSetCommands#zUnionStore(org.reactivestreams.Publisher)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,20 @@ public Long zRemRange(byte[] key, long start, long end) {
return connection.invoke().just(RedisSortedSetAsyncCommands::zremrangebyrank, key, start, end);
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRangeByLex(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Long zRemRangeByLex(byte[] key, Range range) {

Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null for ZREMRANGEBYLEX!");

return connection.invoke().just(RedisSortedSetAsyncCommands::zremrangebylex, key,
LettuceConverters.<byte[]> toRange(range, true));
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRemRangeByScore(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,17 @@ public interface BoundZSetOperations<K, V> extends BoundKeyOperations<K> {
@Nullable
Long removeRange(long start, long end);

/**
* Remove elements in {@link Range} from sorted set with the bound key.
*
* @param range must not be {@literal null}.
* @return {@literal null} when used in pipeline / transaction.
* @since 2.5
* @see <a href="https://redis.io/commands/zremrangebylex">Redis Documentation: ZREMRANGEBYLEX</a>
*/
@Nullable
Long removeRangeByLex(Range range);

/**
* Remove elements with scores between {@code min} and {@code max} from sorted set with the bound key.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,15 @@ public Long removeRange(long start, long end) {
return ops.removeRange(getKey(), start, end);
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.core.BoundZSetOperations#removeRangeByLex(org.springframework.data.redis.connection.RedisZSetCommands.Range)
*/
@Override
public Long removeRangeByLex(Range range) {
return ops.removeRangeByLex(getKey(), range);
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.core.BoundZSetOperations#removeRangeByScore(double, double)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,19 @@ public Mono<Long> removeRange(K key, Range<Long> range) {
return createMono(connection -> connection.zRemRangeByRank(rawKey(key), range));
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.core.ReactiveZSetOperations#removeRangebyLex(java.lang.Object, org.springframework.data.domain.Range)
*/
@Override
public Mono<Long> removeRangeByLex(K key, Range<String> range) {

Assert.notNull(key, "Key must not be null!");
Assert.notNull(range, "Range must not be null!");

return createMono(connection -> connection.zRemRangeByLex(rawKey(key), range));
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.core.ReactiveZSetOperations#removeRangeByScore(java.lang.Object, org.springframework.data.domain.Range)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,17 @@ public Long removeRange(K key, long start, long end) {
return execute(connection -> connection.zRemRange(rawKey, start, end), true);
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.core.ZSetOperations#removeRangeByLex(java.lang.Object, Range)
*/
@Override
public Long removeRangeByLex(K key, Range range) {

byte[] rawKey = rawKey(key);
return execute(connection -> connection.zRemRangeByLex(rawKey, range), true);
}

/*
* (non-Javadoc)
* @see org.springframework.data.redis.core.ZSetOperations#removeRangeByScore(java.lang.Object, double, double)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,17 @@ default Flux<TypedTuple<V>> scan(K key) {
*/
Mono<Long> removeRange(K key, Range<Long> range);

/**
* Remove elements in range from sorted set with {@code key}.
*
* @param key must not be {@literal null}.
* @param range must not be {@literal null}.
* @return a {@link Mono} emitting the number or removed elements.
* @since 2.5
* @see <a href="https://redis.io/commands/zremrangebyrank">Redis Documentation: ZREMRANGEBYRANK</a>
*/
Mono<Long> removeRangeByLex(K key, Range<String> range);

/**
* Remove elements with scores between {@code min} and {@code max} from sorted set with {@code key}.
*
Expand Down
Loading