Skip to content

Commit 62932e2

Browse files
committed
Polishing.
Add reactive ZRANGESTORE support. Support rangeAndStore in RedisZSet. Refine assertion messages. Refine overloads. Original pull request: #2370. See #2345
1 parent 40d078f commit 62932e2

21 files changed

+1412
-148
lines changed

src/main/asciidoc/appendix/appendix-command-reference.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@
181181
|ZRANGEBYLEX |-
182182
|ZREVRANGEBYLEX |-
183183
|ZRANGEBYSCORE |X
184+
|ZRANGESTORE |X
184185
|ZRANK |X
185186
|ZREM |X
186187
|ZREMRANGEBYLEX |-

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

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,6 +2711,12 @@ public Set<byte[]> zRevRangeByLex(byte[] key, org.springframework.data.domain.Ra
27112711
return convertAndReturn(delegate.zRevRangeByLex(key, range, limit), Converters.identityConverter());
27122712
}
27132713

2714+
@Override
2715+
public Set<String> zRevRangeByLex(String key, org.springframework.data.domain.Range<String> range,
2716+
org.springframework.data.redis.connection.Limit limit) {
2717+
return convertAndReturn(delegate.zRevRangeByLex(serialize(key), serialize(range), limit), byteSetToStringSet);
2718+
}
2719+
27142720
@Override
27152721
public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey,
27162722
org.springframework.data.domain.Range<byte[]> range,
@@ -2721,16 +2727,21 @@ public Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey,
27212727

27222728
@Override
27232729
public Long zRangeStoreByLex(String dstKey, String srcKey,
2724-
org.springframework.data.domain.Range<String> range,
2725-
org.springframework.data.redis.connection.Limit limit) {
2730+
org.springframework.data.domain.Range<String> range, org.springframework.data.redis.connection.Limit limit) {
27262731
return convertAndReturn(delegate.zRangeStoreByLex(serialize(dstKey), serialize(srcKey), serialize(range), limit),
27272732
Converters.identityConverter());
27282733
}
27292734

27302735
@Override
2731-
public Long zRangeStoreByScore(String dstKey, String srcKey, double min, double max,
2732-
org.springframework.data.redis.connection.Limit limit) {
2733-
return convertAndReturn(delegate.zRangeStoreByScore(serialize(dstKey), serialize(srcKey), min, max, limit),
2736+
public Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
2737+
org.springframework.data.redis.connection.Limit limit) {
2738+
return convertAndReturn(delegate.zRangeStoreRevByLex(dstKey, srcKey, range, limit), Converters.identityConverter());
2739+
}
2740+
2741+
@Override
2742+
public Long zRangeStoreRevByLex(String dstKey, String srcKey, org.springframework.data.domain.Range<String> range,
2743+
org.springframework.data.redis.connection.Limit limit) {
2744+
return convertAndReturn(delegate.zRangeStoreRevByLex(serialize(dstKey), serialize(srcKey), serialize(range), limit),
27342745
Converters.identityConverter());
27352746
}
27362747

@@ -2743,9 +2754,24 @@ public Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey,
27432754
}
27442755

27452756
@Override
2746-
public Set<String> zRevRangeByLex(String key, org.springframework.data.domain.Range<String> range,
2757+
public Long zRangeStoreByScore(String dstKey, String srcKey, org.springframework.data.domain.Range<Number> range,
27472758
org.springframework.data.redis.connection.Limit limit) {
2748-
return convertAndReturn(delegate.zRevRangeByLex(serialize(key), serialize(range), limit), byteSetToStringSet);
2759+
return convertAndReturn(delegate.zRangeStoreByScore(serialize(dstKey), serialize(srcKey), range, limit),
2760+
Converters.identityConverter());
2761+
}
2762+
2763+
@Override
2764+
public Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
2765+
org.springframework.data.redis.connection.Limit limit) {
2766+
return convertAndReturn(delegate.zRangeStoreRevByScore(dstKey, srcKey, range, limit),
2767+
Converters.identityConverter());
2768+
}
2769+
2770+
@Override
2771+
public Long zRangeStoreRevByScore(String dstKey, String srcKey, org.springframework.data.domain.Range<Number> range,
2772+
org.springframework.data.redis.connection.Limit limit) {
2773+
return convertAndReturn(delegate.zRangeStoreRevByScore(serialize(dstKey), serialize(srcKey), range, limit),
2774+
Converters.identityConverter());
27492775
}
27502776

27512777
@Override

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1846,6 +1846,14 @@ default Long zRangeStoreByLex(byte[] dstKey, byte[] srcKey,
18461846
return zSetCommands().zRangeStoreByLex(dstKey, srcKey, range, limit);
18471847
}
18481848

1849+
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
1850+
@Override
1851+
@Deprecated
1852+
default Long zRangeStoreRevByLex(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<byte[]> range,
1853+
org.springframework.data.redis.connection.Limit limit) {
1854+
return zSetCommands().zRangeStoreRevByLex(dstKey, srcKey, range, limit);
1855+
}
1856+
18491857
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
18501858
@Override
18511859
@Deprecated
@@ -1855,4 +1863,12 @@ default Long zRangeStoreByScore(byte[] dstKey, byte[] srcKey,
18551863
return zSetCommands().zRangeStoreByScore(dstKey, srcKey, range, limit);
18561864
}
18571865

1866+
/** @deprecated in favor of {@link RedisConnection#zSetCommands()}}. */
1867+
@Override
1868+
@Deprecated
1869+
default Long zRangeStoreRevByScore(byte[] dstKey, byte[] srcKey, org.springframework.data.domain.Range<Number> range,
1870+
org.springframework.data.redis.connection.Limit limit) {
1871+
return zSetCommands().zRangeStoreRevByScore(dstKey, srcKey, range, limit);
1872+
}
1873+
18581874
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ public boolean isUnlimited() {
5252
return this.equals(UNLIMITED);
5353
}
5454

55+
public boolean isLimited() {
56+
return !isUnlimited();
57+
}
58+
5559
/**
5660
* @return new {@link Limit} indicating no limit;
5761
* @since 1.3

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

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,250 @@ default Flux<Tuple> zRevRangeWithScores(ByteBuffer key, Range<Long> range) {
902902
*/
903903
Flux<CommandResponse<ZRangeCommand, Flux<Tuple>>> zRange(Publisher<ZRangeCommand> commands);
904904

905+
/**
906+
* {@code ZRANGESTORE} command parameters.
907+
*
908+
* @author Mark Paluch
909+
* @since 3.0
910+
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
911+
*/
912+
class ZRangeStoreCommand extends KeyCommand {
913+
914+
private final ByteBuffer destKey;
915+
private final RangeMode rangeMode;
916+
private final Range<?> range;
917+
private final Direction direction;
918+
private final Limit limit;
919+
920+
private ZRangeStoreCommand(@Nullable ByteBuffer srcKey, @Nullable ByteBuffer destKey, RangeMode rangeMode,
921+
Range<?> range, Direction direction, Limit limit) {
922+
923+
super(srcKey);
924+
this.destKey = destKey;
925+
this.rangeMode = rangeMode;
926+
this.range = range;
927+
this.direction = direction;
928+
this.limit = limit;
929+
}
930+
931+
/**
932+
* Creates a new {@link ZRangeStoreCommand} given a {@link Range} to obtain elements ordered from the lowest to the
933+
* highest score.
934+
*
935+
* @param range must not be {@literal null}.
936+
* @return a new {@link ZRangeCommand} for {@link Tuple}.
937+
*/
938+
public static ZRangeStoreCommand scoreWithin(Range<Double> range) {
939+
940+
Assert.notNull(range, "Range must not be null");
941+
942+
return new ZRangeStoreCommand(null, null, RangeMode.ByScore, range, Direction.ASC, Limit.unlimited());
943+
}
944+
945+
/**
946+
* Creates a new {@link ZRangeStoreCommand} given a {@link Range} to obtain elements ordered from the highest to the
947+
* lowest score.
948+
*
949+
* @param range must not be {@literal null}.
950+
* @return a new {@link ZRangeStoreCommand} for {@link Tuple}.
951+
*/
952+
public static ZRangeStoreCommand reverseScoreWithin(Range<Double> range) {
953+
954+
Assert.notNull(range, "Range must not be null");
955+
956+
return new ZRangeStoreCommand(null, null, RangeMode.ByScore, range, Direction.DESC, Limit.unlimited());
957+
}
958+
959+
/**
960+
* Creates a new {@link ZRangeStoreCommand} given a {@link Range} to obtain elements ordered from the lowest to the
961+
* highest lexicographical value.
962+
*
963+
* @param range must not be {@literal null}.
964+
* @return a new {@link ZRangeCommand} for {@link Tuple}.
965+
*/
966+
public static ZRangeStoreCommand valueWithin(Range<String> range) {
967+
968+
Assert.notNull(range, "Range must not be null");
969+
970+
return new ZRangeStoreCommand(null, null, RangeMode.ByLex, range, Direction.ASC, Limit.unlimited());
971+
}
972+
973+
/**
974+
* Creates a new {@link ZRangeStoreCommand} given a {@link Range} to obtain elements ordered from the highest to the
975+
* lowest lexicographical value.
976+
*
977+
* @param range must not be {@literal null}.
978+
* @return a new {@link ZRangeStoreCommand} for {@link Tuple}.
979+
*/
980+
public static ZRangeStoreCommand reverseValueWithin(Range<String> range) {
981+
982+
Assert.notNull(range, "Range must not be null");
983+
984+
return new ZRangeStoreCommand(null, null, RangeMode.ByLex, range, Direction.DESC, Limit.unlimited());
985+
}
986+
987+
/**
988+
* Applies the {@literal key}. Constructs a new command instance with all previously configured properties.
989+
*
990+
* @param key must not be {@literal null}.
991+
* @return a new {@link ZRangeStoreCommand} with {@literal key} applied.
992+
*/
993+
public ZRangeStoreCommand from(ByteBuffer key) {
994+
995+
Assert.notNull(key, "Key must not be null");
996+
997+
return new ZRangeStoreCommand(key, destKey, rangeMode, range, direction, limit);
998+
}
999+
1000+
/**
1001+
* Applies the {@literal key}. Constructs a new command instance with all previously configured properties.
1002+
*
1003+
* @param key must not be {@literal null}.
1004+
* @return a new {@link ZRangeStoreCommand} with {@literal key} applied.
1005+
*/
1006+
public ZRangeStoreCommand to(ByteBuffer key) {
1007+
1008+
Assert.notNull(key, "Key must not be null");
1009+
1010+
return new ZRangeStoreCommand(getKey(), key, rangeMode, range, direction, limit);
1011+
}
1012+
1013+
/**
1014+
* Applies the {@literal limit}. Constructs a new command instance with all previously configured properties.
1015+
*
1016+
* @param limit must not be {@literal null}.
1017+
* @return a new {@link ZRangeStoreCommand} with {@literal key} applied.
1018+
*/
1019+
public ZRangeStoreCommand limit(Limit limit) {
1020+
1021+
Assert.notNull(limit, "Limit must not be null");
1022+
1023+
return new ZRangeStoreCommand(getKey(), getDestKey(), rangeMode, range, direction, limit);
1024+
}
1025+
1026+
public ByteBuffer getDestKey() {
1027+
return destKey;
1028+
}
1029+
1030+
public RangeMode getRangeMode() {
1031+
return rangeMode;
1032+
}
1033+
1034+
public Range<?> getRange() {
1035+
return range;
1036+
}
1037+
1038+
public Direction getDirection() {
1039+
return direction;
1040+
}
1041+
1042+
public Limit getLimit() {
1043+
return limit;
1044+
}
1045+
1046+
public enum RangeMode {
1047+
ByScore, ByLex,
1048+
}
1049+
}
1050+
1051+
/**
1052+
* Add elements from {@code srcKey} by score {@literal range} to {@code destKey}.
1053+
*
1054+
* @param srcKey must not be {@literal null}.
1055+
* @param destKey must not be {@literal null}.
1056+
* @param range must not be {@literal null}.
1057+
* @param limit must not be {@literal null}.
1058+
* @return
1059+
* @since 3.0
1060+
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
1061+
*/
1062+
default Mono<Long> zRangeStoreByScore(ByteBuffer srcKey, ByteBuffer destKey, Range<Double> range, Limit limit) {
1063+
1064+
Assert.notNull(srcKey, "Source key must not be null");
1065+
Assert.notNull(destKey, "Destination key must not be null");
1066+
Assert.notNull(range, "Range must not be null");
1067+
Assert.notNull(limit, "Limit must not be null");
1068+
1069+
return zRangeStore(Mono.just(ZRangeStoreCommand.scoreWithin(range).from(srcKey).to(destKey).limit(limit))) //
1070+
.flatMap(CommandResponse::getOutput).next();
1071+
}
1072+
1073+
/**
1074+
* Add elements from {@code srcKey} by lexicographical {@literal range} to {@code destKey}.
1075+
*
1076+
* @param srcKey must not be {@literal null}.
1077+
* @param destKey must not be {@literal null}.
1078+
* @param range must not be {@literal null}.
1079+
* @param limit must not be {@literal null}.
1080+
* @return
1081+
* @since 3.0
1082+
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
1083+
*/
1084+
default Mono<Long> zRangeStoreByLex(ByteBuffer srcKey, ByteBuffer destKey, Range<String> range, Limit limit) {
1085+
1086+
Assert.notNull(srcKey, "Source key must not be null");
1087+
Assert.notNull(destKey, "Destination key must not be null");
1088+
Assert.notNull(range, "Range must not be null");
1089+
Assert.notNull(limit, "Limit must not be null");
1090+
1091+
return zRangeStore(Mono.just(ZRangeStoreCommand.valueWithin(range).from(srcKey).to(destKey).limit(limit))) //
1092+
.flatMap(CommandResponse::getOutput).next();
1093+
}
1094+
1095+
/**
1096+
* Add elements from {@code srcKey} by reverse score {@literal range} to {@code destKey}.
1097+
*
1098+
* @param srcKey must not be {@literal null}.
1099+
* @param destKey must not be {@literal null}.
1100+
* @param range must not be {@literal null}.
1101+
* @param limit must not be {@literal null}.
1102+
* @return
1103+
* @since 3.0
1104+
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
1105+
*/
1106+
default Mono<Long> zRangeStoreRevByScore(ByteBuffer srcKey, ByteBuffer destKey, Range<Double> range, Limit limit) {
1107+
1108+
Assert.notNull(srcKey, "Source key must not be null");
1109+
Assert.notNull(destKey, "Destination key must not be null");
1110+
Assert.notNull(range, "Range must not be null");
1111+
Assert.notNull(limit, "Limit must not be null");
1112+
1113+
return zRangeStore(Mono.just(ZRangeStoreCommand.reverseScoreWithin(range).from(srcKey).to(destKey).limit(limit))) //
1114+
.flatMap(CommandResponse::getOutput).next();
1115+
}
1116+
1117+
/**
1118+
* Add elements from {@code srcKey} by reverse lexicographical {@literal range} to {@code destKey}.
1119+
*
1120+
* @param srcKey must not be {@literal null}.
1121+
* @param destKey must not be {@literal null}.
1122+
* @param range must not be {@literal null}.
1123+
* @param limit must not be {@literal null}.
1124+
* @return
1125+
* @since 3.0
1126+
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
1127+
*/
1128+
default Mono<Long> zRangeStoreRevByLex(ByteBuffer srcKey, ByteBuffer destKey, Range<String> range, Limit limit) {
1129+
1130+
Assert.notNull(srcKey, "Source key must not be null");
1131+
Assert.notNull(destKey, "Destination key must not be null");
1132+
Assert.notNull(range, "Range must not be null");
1133+
Assert.notNull(limit, "Limit must not be null");
1134+
1135+
return zRangeStore(Mono.just(ZRangeStoreCommand.reverseValueWithin(range).from(srcKey).to(destKey).limit(limit))) //
1136+
.flatMap(CommandResponse::getOutput).next();
1137+
}
1138+
1139+
/**
1140+
* Get set of {@link Tuple}s in {@literal range} from sorted set.
1141+
*
1142+
* @param commands must not be {@literal null}.
1143+
* @return
1144+
* @since 3.0
1145+
* @see <a href="https://redis.io/commands/zrangestore">Redis Documentation: ZRANGESTORE</a>
1146+
*/
1147+
Flux<CommandResponse<ZRangeStoreCommand, Mono<Long>>> zRangeStore(Publisher<ZRangeStoreCommand> commands);
1148+
9051149
/**
9061150
* {@literal ZRANGEBYSCORE}/{@literal ZREVRANGEBYSCORE}.
9071151
*

0 commit comments

Comments
 (0)