Skip to content

Commit da81275

Browse files
anshlykovmp911de
authored andcommitted
DATAREDIS-729 - Add support for ZREVRANGEBYLEX command.
Original pull request: #566.
1 parent 0f54fcf commit da81275

File tree

8 files changed

+289
-6
lines changed

8 files changed

+289
-6
lines changed

src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3639,6 +3639,24 @@ public Set<String> zRangeByLex(String key, Range range, Limit limit) {
36393639
return convertAndReturn(delegate.zRangeByLex(serialize(key), range, limit), byteSetToStringSet);
36403640
}
36413641

3642+
/*
3643+
* (non-Javadoc)
3644+
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByLex(java.lang.String, org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
3645+
*/
3646+
@Override
3647+
public Set<byte[]> zRevRangeByLex(byte[] key, Range range, Limit limit) {
3648+
return convertAndReturn(delegate.zRevRangeByLex(key, range, limit), identityConverter);
3649+
}
3650+
3651+
/*
3652+
* (non-Javadoc)
3653+
* @see org.springframework.data.redis.connection.StringRedisConnection#zRevRangeByLex(java.lang.String, org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
3654+
*/
3655+
@Override
3656+
public Set<String> zRevRangeByLex(String key, Range range, Limit limit) {
3657+
return convertAndReturn(delegate.zRevRangeByLex(serialize(key), range, limit), byteSetToStringSet);
3658+
}
3659+
36423660
/*
36433661
* (non-Javadoc)
36443662
* @see org.springframework.data.redis.connection.RedisServerCommands#migrate(byte[], org.springframework.data.redis.connection.RedisNode, int, org.springframework.data.redis.connection.RedisServerCommands.MigrateOption)

src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,13 @@ default Set<byte[]> zRangeByLex(byte[] key, Range range, Limit limit) {
953953
return zSetCommands().zRangeByLex(key, range, limit);
954954
}
955955

956+
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
957+
@Override
958+
@Deprecated
959+
default Set<byte[]> zRevRangeByLex(byte[] key, Range range, Limit limit) {
960+
return zSetCommands().zRevRangeByLex(key, range, limit);
961+
}
962+
956963
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
957964
@Override
958965
@Deprecated

src/main/java/org/springframework/data/redis/connection/RedisZSetCommands.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
* @author Thomas Darimont
4040
* @author David Liu
4141
* @author Mark Paluch
42+
* @author Andrey Shlykov
4243
*/
4344
public interface RedisZSetCommands {
4445

@@ -1017,4 +1018,45 @@ default Set<byte[]> zRangeByLex(byte[] key, Range range) {
10171018
@Nullable
10181019
Set<byte[]> zRangeByLex(byte[] key, Range range, Limit limit);
10191020

1021+
/**
1022+
* Get all the elements in the sorted set at {@literal key} in reversed lexicographical ordering.
1023+
*
1024+
* @param key must not be {@literal null}.
1025+
* @return {@literal null} when used in pipeline / transaction.
1026+
* @since 2.4
1027+
* @see <a href="https://redis.io/commands/zrevrangebylex">Redis Documentation: ZREVRANGEBYLEX</a>
1028+
*/
1029+
@Nullable
1030+
default Set<byte[]> zRevRangeByLex(byte[] key) {
1031+
return zRevRangeByLex(key, Range.unbounded());
1032+
}
1033+
1034+
/**
1035+
* Get all the elements in {@link Range} from the sorted set at {@literal key} in reversed lexicographical ordering.
1036+
*
1037+
* @param key must not be {@literal null}.
1038+
* @param range must not be {@literal null}.
1039+
* @return {@literal null} when used in pipeline / transaction.
1040+
* @since 2.4
1041+
* @see <a href="https://redis.io/commands/zrevrangebylex">Redis Documentation: ZREVRANGEBYLEX</a>
1042+
*/
1043+
@Nullable
1044+
default Set<byte[]> zRevRangeByLex(byte[] key, Range range) {
1045+
return zRevRangeByLex(key, range, Limit.unlimited());
1046+
}
1047+
1048+
/**
1049+
* Get all the elements in {@link Range} from the sorted set at {@literal key} in reversed lexicographical ordering. Result is
1050+
* limited via {@link Limit}.
1051+
*
1052+
* @param key must not be {@literal null}.
1053+
* @param range must not be {@literal null}.
1054+
* @param limit must not be {@literal null}.
1055+
* @return {@literal null} when used in pipeline / transaction.
1056+
* @since 2.4
1057+
* @see <a href="https://redis.io/commands/zrevrangebylex">Redis Documentation: ZREVRANGEBYLEX</a>
1058+
*/
1059+
@Nullable
1060+
Set<byte[]> zRevRangeByLex(byte[] key, Range range, Limit limit);
1061+
10201062
}

src/main/java/org/springframework/data/redis/connection/StringRedisConnection.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
* @author Ninad Divadkar
6464
* @author Tugdual Grall
6565
* @author Dengliming
66+
* @author Andrey Shlykov
6667
* @see RedisCallback
6768
* @see RedisSerializer
6869
* @see StringRedisTemplate
@@ -1499,6 +1500,47 @@ default Long lPos(String key, String element) {
14991500
*/
15001501
Set<String> zRangeByLex(String key, Range range, Limit limit);
15011502

1503+
/**
1504+
* Get all the elements in the sorted set at {@literal key} in reversed lexicographical ordering.
1505+
*
1506+
* @param key must not be {@literal null}.
1507+
* @return
1508+
* @since 2.4
1509+
* @see <a href="https://redis.io/commands/zrevrangebylex">Redis Documentation: ZREVRANGEBYLEX</a>
1510+
* @see RedisZSetCommands#zRevRangeByLex(byte[])
1511+
*/
1512+
default Set<String> zRevRangeByLex(String key) {
1513+
return zRevRangeByLex(key, Range.unbounded());
1514+
}
1515+
1516+
/**
1517+
* Get all the elements in {@link Range} from the sorted set at {@literal key} in reversed lexicographical ordering.
1518+
*
1519+
* @param key must not be {@literal null}.
1520+
* @param range must not be {@literal null}.
1521+
* @return
1522+
* @since 2.4
1523+
* @see <a href="https://redis.io/commands/zrevrangebylex">Redis Documentation: ZREVRANGEBYLEX</a>
1524+
* @see RedisZSetCommands#zRevRangeByLex(byte[], Range)
1525+
*/
1526+
default Set<String> zRevRangeByLex(String key, Range range) {
1527+
return zRevRangeByLex(key, range, Limit.unlimited());
1528+
}
1529+
1530+
/**
1531+
* Get all the elements in {@link Range} from the sorted set at {@literal key} in reversed lexicographical ordering. Result is
1532+
* limited via {@link Limit}.
1533+
*
1534+
* @param key must not be {@literal null}.
1535+
* @param range must not be {@literal null}.
1536+
* @param range can be {@literal null}.
1537+
* @return
1538+
* @since 2.4
1539+
* @see <a href="https://redis.io/commands/zrevrangebylex">Redis Documentation: ZREVRANGEBYLEX</a>
1540+
* @see RedisZSetCommands#zRevRangeByLex(byte[], Range, Limit)
1541+
*/
1542+
Set<String> zRevRangeByLex(String key, Range range, Limit limit);
1543+
15021544
// -------------------------------------------------------------------------
15031545
// Methods dealing with Redis Hashes
15041546
// -------------------------------------------------------------------------

src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterZSetCommands.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
* @author Christoph Strobl
3636
* @author Mark Paluch
3737
* @author Clement Ong
38+
* @author Andrey Shlykov
3839
* @since 2.0
3940
*/
4041
class JedisClusterZSetCommands implements RedisZSetCommands {
@@ -324,6 +325,30 @@ public Set<byte[]> zRangeByLex(byte[] key, Range range, Limit limit) {
324325
}
325326
}
326327

328+
/*
329+
* (non-Javadoc)
330+
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByLex(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
331+
*/
332+
@Override
333+
public Set<byte[]> zRevRangeByLex(byte[] key, Range range, Limit limit) {
334+
335+
Assert.notNull(key, "Key must not be null!");
336+
Assert.notNull(range, "Range cannot be null for ZREVRANGEBYLEX.");
337+
Assert.notNull(limit, "Limit must not be null!");
338+
339+
byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES);
340+
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES);
341+
342+
try {
343+
if (limit.isUnlimited()) {
344+
return connection.getCluster().zrevrangeByLex(key, min, max);
345+
}
346+
return connection.getCluster().zrevrangeByLex(key, min, max, limit.getOffset(), limit.getCount());
347+
} catch (Exception ex) {
348+
throw convertJedisAccessException(ex);
349+
}
350+
}
351+
327352
/*
328353
* (non-Javadoc)
329354
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRangeWithScores(byte[], long, long)

src/main/java/org/springframework/data/redis/connection/jedis/JedisZSetCommands.java

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@
2020
import redis.clients.jedis.ZParams;
2121

2222
import java.nio.charset.StandardCharsets;
23+
import java.util.LinkedHashSet;
2324
import java.util.Set;
2425

2526
import org.springframework.data.redis.connection.RedisZSetCommands;
2627
import org.springframework.data.redis.core.Cursor;
2728
import org.springframework.data.redis.core.KeyBoundCursor;
2829
import org.springframework.data.redis.core.ScanIteration;
2930
import org.springframework.data.redis.core.ScanOptions;
30-
import org.springframework.lang.Nullable;
3131
import org.springframework.util.Assert;
3232

3333
/**
@@ -897,6 +897,50 @@ public Set<byte[]> zRangeByLex(byte[] key, Range range, Limit limit) {
897897
}
898898
}
899899

900+
/*
901+
* (non-Javadoc)
902+
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByLex(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
903+
*/
904+
@Override
905+
public Set<byte[]> zRevRangeByLex(byte[] key, Range range, Limit limit) {
906+
907+
Assert.notNull(key, "Key must not be null!");
908+
Assert.notNull(range, "Range for ZREVRANGEBYLEX must not be null!");
909+
Assert.notNull(limit, "Limit must not be null! Use Limit.unlimited() instead.");
910+
911+
byte[] min = JedisConverters.boundaryToBytesForZRangeByLex(range.getMin(), JedisConverters.MINUS_BYTES);
912+
byte[] max = JedisConverters.boundaryToBytesForZRangeByLex(range.getMax(), JedisConverters.PLUS_BYTES);
913+
914+
try {
915+
if (isPipelined()) {
916+
if (!limit.isUnlimited()) {
917+
pipeline(connection.newJedisResult(
918+
connection.getRequiredPipeline().zrevrangeByLex(key, max, min, limit.getOffset(), limit.getCount())));
919+
} else {
920+
pipeline(connection.newJedisResult(connection.getRequiredPipeline().zrevrangeByLex(key, max, min)));
921+
}
922+
return null;
923+
}
924+
925+
if (isQueueing()) {
926+
if (!limit.isUnlimited()) {
927+
transaction(connection.newJedisResult(
928+
connection.getRequiredTransaction().zrevrangeByLex(key, max, min, limit.getOffset(), limit.getCount())));
929+
} else {
930+
transaction(connection.newJedisResult(connection.getRequiredTransaction().zrevrangeByLex(key, max, min)));
931+
}
932+
return null;
933+
}
934+
935+
if (!limit.isUnlimited()) {
936+
return new LinkedHashSet<>(connection.getJedis().zrevrangeByLex(key, max, min, limit.getOffset(), limit.getCount()));
937+
}
938+
return new LinkedHashSet<>(connection.getJedis().zrevrangeByLex(key, max, min));
939+
} catch (Exception ex) {
940+
throw convertJedisAccessException(ex);
941+
}
942+
}
943+
900944
private boolean isPipelined() {
901945
return connection.isPipelined();
902946
}

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceZSetCommands.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
/**
3838
* @author Christoph Strobl
3939
* @author Mark Paluch
40+
* @author Andrey Shlykov
4041
* @since 2.0
4142
*/
4243
class LettuceZSetCommands implements RedisZSetCommands {
@@ -877,6 +878,55 @@ public Set<byte[]> zRangeByLex(byte[] key, Range range, Limit limit) {
877878
}
878879
}
879880

881+
/*
882+
* (non-Javadoc)
883+
* @see org.springframework.data.redis.connection.RedisZSetCommands#zRevRangeByLex(byte[], org.springframework.data.redis.connection.RedisZSetCommands.Range, org.springframework.data.redis.connection.RedisZSetCommands.Limit)
884+
*/
885+
@Override
886+
public Set<byte[]> zRevRangeByLex(byte[] key, Range range, Limit limit) {
887+
888+
Assert.notNull(key, "Key must not be null!");
889+
Assert.notNull(range, "Range for ZREVRANGEBYLEX must not be null!");
890+
Assert.notNull(limit, "Limit must not be null!");
891+
892+
try {
893+
if (isPipelined()) {
894+
if (limit.isUnlimited()) {
895+
pipeline(
896+
connection.newLettuceResult(getAsyncConnection().zrevrangebylex(key, LettuceConverters.toRange(range, true)),
897+
LettuceConverters.bytesListToBytesSet()));
898+
} else {
899+
pipeline(
900+
connection.newLettuceResult(getAsyncConnection().zrevrangebylex(key, LettuceConverters.toRange(range, true),
901+
LettuceConverters.toLimit(limit)), LettuceConverters.bytesListToBytesSet()));
902+
}
903+
return null;
904+
}
905+
if (isQueueing()) {
906+
if (limit.isUnlimited()) {
907+
transaction(
908+
connection.newLettuceResult(getAsyncConnection().zrevrangebylex(key, LettuceConverters.toRange(range, true)),
909+
LettuceConverters.bytesListToBytesSet()));
910+
} else {
911+
transaction(
912+
connection.newLettuceResult(getAsyncConnection().zrevrangebylex(key, LettuceConverters.toRange(range, true),
913+
LettuceConverters.toLimit(limit)), LettuceConverters.bytesListToBytesSet()));
914+
}
915+
return null;
916+
}
917+
918+
if (limit.isUnlimited()) {
919+
return LettuceConverters.bytesListToBytesSet()
920+
.convert(getConnection().zrevrangebylex(key, LettuceConverters.toRange(range, true)));
921+
}
922+
return LettuceConverters.bytesListToBytesSet().convert(
923+
getConnection().zrevrangebylex(key, LettuceConverters.toRange(range, true), LettuceConverters.toLimit(limit)));
924+
925+
} catch (Exception ex) {
926+
throw convertLettuceAccessException(ex);
927+
}
928+
}
929+
880930
private boolean isPipelined() {
881931
return connection.isPipelined();
882932
}

0 commit comments

Comments
 (0)