diff --git a/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java b/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java index 80bcf03099..514acc5c02 100644 --- a/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java +++ b/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java @@ -1832,6 +1832,21 @@ public RedisFuture zcount(K key, Range range) { return dispatch(commandBuilder.zcount(key, range)); } + @Override + public RedisFuture> zdiff(K... keys) { + return dispatch(commandBuilder.zdiff(keys)); + } + + @Override + public RedisFuture zdiffstore(K destKey, K... srcKeys) { + return dispatch(commandBuilder.zdiffstore(destKey, srcKeys)); + } + + @Override + public RedisFuture>> zdiffWithScores(K... keys) { + return dispatch(commandBuilder.zdiffWithScores(keys)); + } + @Override public RedisFuture zincrby(K key, double amount, V member) { return dispatch(commandBuilder.zincrby(key, amount, member)); diff --git a/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java b/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java index 8371961b30..d4df2cd278 100644 --- a/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java +++ b/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java @@ -1907,6 +1907,21 @@ public Mono zcount(K key, Range range) { return createMono(() -> commandBuilder.zcount(key, range)); } + @Override + public Flux zdiff(K... keys) { + return createDissolvingFlux(() -> commandBuilder.zdiff(keys)); + } + + @Override + public Mono zdiffstore(K destKey, K... srcKeys) { + return createMono(() -> commandBuilder.zdiffstore(destKey, srcKeys)); + } + + @Override + public Flux> zdiffWithScores(K... keys) { + return createDissolvingFlux(() -> commandBuilder.zdiffWithScores(keys)); + } + @Override public Mono zincrby(K key, double amount, V member) { return createMono(() -> commandBuilder.zincrby(key, amount, member)); diff --git a/src/main/java/io/lettuce/core/RedisCommandBuilder.java b/src/main/java/io/lettuce/core/RedisCommandBuilder.java index 9d5de2f8a6..4268d85a6c 100644 --- a/src/main/java/io/lettuce/core/RedisCommandBuilder.java +++ b/src/main/java/io/lettuce/core/RedisCommandBuilder.java @@ -2674,6 +2674,32 @@ Command zcount(K key, Range range) { return createCommand(ZCOUNT, new IntegerOutput<>(codec), args); } + Command > zdiff(K... keys) { + notEmpty(keys); + + CommandArgs args = new CommandArgs<>(codec); + args.add(keys.length).addKeys(keys); + System.out.println(args); + return createCommand(ZDIFF, new ValueListOutput<>(codec), args); + } + + Command zdiffstore(K destKey, K... srcKeys) { + notNullKey(destKey); + notEmpty(srcKeys); + + CommandArgs args = new CommandArgs<>(codec); + args.addKey(destKey).add(srcKeys.length).addKeys(srcKeys); + return createCommand(ZDIFFSTORE, new IntegerOutput<>(codec), args); + } + + Command>> zdiffWithScores(K... keys) { + notEmpty(keys); + + CommandArgs args = new CommandArgs<>(codec); + args.add(keys.length).addKeys(keys).add(WITHSCORES); + return createCommand(ZDIFF, new ScoredValueListOutput<>(codec), args); + } + Command zincrby(K key, double amount, V member) { notNullKey(key); diff --git a/src/main/java/io/lettuce/core/api/async/RedisSortedSetAsyncCommands.java b/src/main/java/io/lettuce/core/api/async/RedisSortedSetAsyncCommands.java index 7ba55a1844..b0eae45a57 100644 --- a/src/main/java/io/lettuce/core/api/async/RedisSortedSetAsyncCommands.java +++ b/src/main/java/io/lettuce/core/api/async/RedisSortedSetAsyncCommands.java @@ -198,6 +198,34 @@ public interface RedisSortedSetAsyncCommands { */ RedisFuture zcount(K key, Range range); + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return List<V> array-reply list of elements. + * @since 6.2 + */ + RedisFuture> zdiff(K... keys); + + /** + * Computes the difference between the first and all successive input sorted sets and stores the result in destination. + * + * @param destKey the dest key. + * @param srcKeys the src keys. + * @return Long the number of elements in the resulting sorted set at destination. + * @since 6.2 + */ + RedisFuture zdiffstore(K destKey, K... srcKeys); + + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return List<V> array-reply list of scored values. + * @since 6.2 + */ + RedisFuture>> zdiffWithScores(K... keys); + /** * Increment the score of a member in a sorted set. * diff --git a/src/main/java/io/lettuce/core/api/reactive/RedisSortedSetReactiveCommands.java b/src/main/java/io/lettuce/core/api/reactive/RedisSortedSetReactiveCommands.java index 05de2e3408..98fbe6407a 100644 --- a/src/main/java/io/lettuce/core/api/reactive/RedisSortedSetReactiveCommands.java +++ b/src/main/java/io/lettuce/core/api/reactive/RedisSortedSetReactiveCommands.java @@ -200,6 +200,34 @@ public interface RedisSortedSetReactiveCommands { */ Mono zcount(K key, Range range); + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return V array-reply list of elements. + * @since 6.2 + */ + Flux zdiff(K... keys); + + /** + * Computes the difference between the first and all successive input sorted sets and stores the result in destination. + * + * @param destKey the dest key. + * @param srcKeys the src keys. + * @return Long the number of elements in the resulting sorted set at destination. + * @since 6.2 + */ + Mono zdiffstore(K destKey, K... srcKeys); + + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return V array-reply list of scored values. + * @since 6.2 + */ + Flux> zdiffWithScores(K... keys); + /** * Increment the score of a member in a sorted set. * diff --git a/src/main/java/io/lettuce/core/api/sync/RedisSortedSetCommands.java b/src/main/java/io/lettuce/core/api/sync/RedisSortedSetCommands.java index 89c4a2b73f..da14ae9710 100644 --- a/src/main/java/io/lettuce/core/api/sync/RedisSortedSetCommands.java +++ b/src/main/java/io/lettuce/core/api/sync/RedisSortedSetCommands.java @@ -198,6 +198,34 @@ public interface RedisSortedSetCommands { */ Long zcount(K key, Range range); + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return List<V> array-reply list of elements. + * @since 6.2 + */ + List zdiff(K... keys); + + /** + * Computes the difference between the first and all successive input sorted sets and stores the result in destination. + * + * @param destKey the dest key. + * @param srcKeys the src keys. + * @return Long the number of elements in the resulting sorted set at destination. + * @since 6.2 + */ + Long zdiffstore(K destKey, K... srcKeys); + + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return List<V> array-reply list of scored values. + * @since 6.2 + */ + List> zdiffWithScores(K... keys); + /** * Increment the score of a member in a sorted set. * diff --git a/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionSortedSetAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionSortedSetAsyncCommands.java index 1c7c13545a..cf0e3c4d35 100644 --- a/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionSortedSetAsyncCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionSortedSetAsyncCommands.java @@ -198,6 +198,34 @@ public interface NodeSelectionSortedSetAsyncCommands { */ AsyncExecutions zcount(K key, Range range); + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return List<V> array-reply list of elements. + * @since 6.2 + */ + AsyncExecutions> zdiff(K... keys); + + /** + * Computes the difference between the first and all successive input sorted sets and stores the result in destination. + * + * @param destKey the dest key. + * @param srcKeys the src keys. + * @return Long the number of elements in the resulting sorted set at destination. + * @since 6.2 + */ + AsyncExecutions zdiffstore(K destKey, K... srcKeys); + + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return List<V> array-reply list of scored values. + * @since 6.2 + */ + AsyncExecutions>> zdiffWithScores(K... keys); + /** * Increment the score of a member in a sorted set. * diff --git a/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionSortedSetCommands.java b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionSortedSetCommands.java index 167a16a5e9..4c22327e37 100644 --- a/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionSortedSetCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionSortedSetCommands.java @@ -198,6 +198,34 @@ public interface NodeSelectionSortedSetCommands { */ Executions zcount(K key, Range range); + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return List<V> array-reply list of elements. + * @since 6.2 + */ + Executions> zdiff(K... keys); + + /** + * Computes the difference between the first and all successive input sorted sets and stores the result in destination. + * + * @param destKey the dest key. + * @param srcKeys the src keys. + * @return Long the number of elements in the resulting sorted set at destination. + * @since 6.2 + */ + Executions zdiffstore(K destKey, K... srcKeys); + + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return List<V> array-reply list of scored values. + * @since 6.2 + */ + Executions>> zdiffWithScores(K... keys); + /** * Increment the score of a member in a sorted set. * diff --git a/src/main/java/io/lettuce/core/protocol/CommandType.java b/src/main/java/io/lettuce/core/protocol/CommandType.java index f80272f0be..8fe3b4530b 100644 --- a/src/main/java/io/lettuce/core/protocol/CommandType.java +++ b/src/main/java/io/lettuce/core/protocol/CommandType.java @@ -78,7 +78,7 @@ public enum CommandType implements ProtocolKeyword { // Sorted Set - BZPOPMIN, BZPOPMAX, ZADD, ZCARD, ZCOUNT, ZINCRBY, ZINTER, ZINTERSTORE, ZLEXCOUNT, ZMSCORE, ZPOPMIN, ZPOPMAX, ZRANGE, ZRANGEBYSCORE, ZRANK, ZREM, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZREVRANGE, ZREVRANGEBYLEX, ZREVRANGEBYSCORE, ZREVRANK, ZSCAN, ZSCORE, ZUNION, ZUNIONSTORE, ZREMRANGEBYLEX, ZRANGEBYLEX, + BZPOPMIN, BZPOPMAX, ZADD, ZCARD, ZCOUNT, ZDIFF, ZDIFFSTORE, ZINCRBY, ZINTER, ZINTERSTORE, ZLEXCOUNT, ZMSCORE, ZPOPMIN, ZPOPMAX, ZRANGE, ZRANGEBYSCORE, ZRANK, ZREM, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZREVRANGE, ZREVRANGEBYLEX, ZREVRANGEBYSCORE, ZREVRANK, ZSCAN, ZSCORE, ZUNION, ZUNIONSTORE, ZREMRANGEBYLEX, ZRANGEBYLEX, // Scripting diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisSortedSetCoroutinesCommands.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisSortedSetCoroutinesCommands.kt index b21bf6049c..35af8aa3ec 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisSortedSetCoroutinesCommands.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisSortedSetCoroutinesCommands.kt @@ -173,6 +173,34 @@ interface RedisSortedSetCoroutinesCommands { */ suspend fun zcount(key: K, range: Range): Long? + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return List array-reply list of elements. + * @since 6.2 + */ + fun zdiff(vararg keys: K): Flow + + /** + * Computes the difference between the first and all successive input sorted sets and stores the result in destination. + * + * @param destKey the dest key. + * @param srcKeys the src keys. + * @return Long the number of elements in the resulting sorted set at destination. + * @since 6.2 + */ + suspend fun zdiffstore(destKey: K, vararg srcKeys: K): Long? + + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return List array-reply list of scored values. + * @since 6.2 + */ + fun zdiffWithScores(vararg keys: K): Flow> + /** * Increment the score of a member in a sorted set. * diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisSortedSetCoroutinesCommandsImpl.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisSortedSetCoroutinesCommandsImpl.kt index e3f0a6b7f2..cf94a6370a 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisSortedSetCoroutinesCommandsImpl.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisSortedSetCoroutinesCommandsImpl.kt @@ -60,6 +60,12 @@ internal class RedisSortedSetCoroutinesCommandsImpl(internal v override suspend fun zcount(key: K, range: Range): Long? = ops.zcount(key, range).awaitFirstOrNull() + override fun zdiff(vararg keys: K): Flow = ops.zdiff(*keys).asFlow() + + override suspend fun zdiffstore(destKey: K, vararg srcKeys: K): Long? = ops.zdiffstore(destKey, *srcKeys).awaitFirstOrNull() + + override fun zdiffWithScores(vararg keys: K): Flow> = ops.zdiffWithScores(*keys).asFlow() + override suspend fun zincrby(key: K, amount: Double, member: V): Double? = ops.zincrby(key, amount, member).awaitFirstOrNull() override fun zinter(vararg keys: K): Flow = ops.zinter(*keys).asFlow() diff --git a/src/main/templates/io/lettuce/core/api/RedisSortedSetCommands.java b/src/main/templates/io/lettuce/core/api/RedisSortedSetCommands.java index d34c1e6869..cfd1fdc9a1 100644 --- a/src/main/templates/io/lettuce/core/api/RedisSortedSetCommands.java +++ b/src/main/templates/io/lettuce/core/api/RedisSortedSetCommands.java @@ -197,6 +197,34 @@ public interface RedisSortedSetCommands { */ Long zcount(K key, Range range); + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return List<V> array-reply list of elements. + * @since 6.2 + */ + List zdiff(K... keys); + + /** + * Computes the difference between the first and all successive input sorted sets and stores the result in destination. + * + * @param destKey the dest key. + * @param srcKeys the src keys. + * @return Long the number of elements in the resulting sorted set at destination. + * @since 6.2 + */ + Long zdiffstore(K destKey, K... srcKeys); + + /** + * Computes the difference between the first and all successive input sorted sets. + * + * @param keys the keys. + * @return List<V> array-reply list of scored values. + * @since 6.2 + */ + List> zdiffWithScores(K... keys); + /** * Increment the score of a member in a sorted set. * diff --git a/src/test/java/io/lettuce/apigenerator/KotlinCompilationUnitFactory.java b/src/test/java/io/lettuce/apigenerator/KotlinCompilationUnitFactory.java index dfef04d055..eb895dcb48 100644 --- a/src/test/java/io/lettuce/apigenerator/KotlinCompilationUnitFactory.java +++ b/src/test/java/io/lettuce/apigenerator/KotlinCompilationUnitFactory.java @@ -61,7 +61,7 @@ class KotlinCompilationUnitFactory { private static final Set SKIP_METHODS = LettuceSets.unmodifiableSet("BaseRedisCommands.reset", "getStatefulConnection"); private static final Set FLOW_METHODS = LettuceSets.unmodifiableSet("dispatch", "geohash", "georadius", "georadiusbymember", "hgetall", "hkeys", "hmget", "hvals", "keys", "mget", "sdiff", "sinter", "smembers", "smismember", "sort", "srandmember", "sunion", - "xclaim", "xpending", "xrange", "xread", "xreadgroup", "xrevrange", "zinter", "zinterWithScores", "zpopmax", "zpopmin", "zrange", + "xclaim", "xpending", "xrange", "xread", "xreadgroup", "xrevrange", "zdiff", "zdiffWithScores", "zinter", "zinterWithScores", "zpopmax", "zpopmin", "zrange", "zrangeWithScores", "zrangebylex", "zrangebyscore", "zrangebyscoreWithScores", "zrevrange", "zrevrangeWithScores", "zrevrangebylex", "zrevrangebyscore", "zrevrangebyscore", "zrevrangebyscoreWithScores", "zunion", "zunionWithScores"); @@ -111,7 +111,7 @@ public void create() throws Exception { CompilationUnit template = JavaParser.parse(templateFile); JavaToken license = template.getTokenRange().get().getBegin(); - result.append(license.asString().replaceAll("Copyright [\\d]{4}-[\\d]{4}", "Copyright 2020-$2")); + result.append(license.asString().replaceAll("Copyright ([\\d]{4})-([\\d]{4})", "Copyright 2020-$2")); result.append(license.getNextToken().get().asString()); result.append("\n"); diff --git a/src/test/java/io/lettuce/core/commands/SortedSetCommandIntegrationTests.java b/src/test/java/io/lettuce/core/commands/SortedSetCommandIntegrationTests.java index 6538408f64..7fcf88c18a 100644 --- a/src/test/java/io/lettuce/core/commands/SortedSetCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/commands/SortedSetCommandIntegrationTests.java @@ -212,6 +212,38 @@ void zcount() { assertThat(redis.zcount(key, Range.unbounded())).isEqualTo(3); } + @Test + @EnabledOnCommand("ZDIFF") // Redis 6.2 + void zdiff() { + String zset1 = "zset1"; + String zset2 = "zset2"; + + assertThat(redis.zadd(zset1, 1.0, "one")).isEqualTo(1); + assertThat(redis.zadd(zset1, 2.0, "two")).isEqualTo(1); + assertThat(redis.zadd(zset1, 3.0, "three")).isEqualTo(1); + assertThat(redis.zadd(zset2, 1.0, "one")).isEqualTo(1); + assertThat(redis.zadd(zset2, 2.0, "two")).isEqualTo(1); + + assertThat(redis.zdiff(zset1, zset2)).isEqualTo(list("three")); + assertThat(redis.zdiffWithScores(zset1, zset2)).isEqualTo(svlist(sv(3.0, "three"))); + } + + @Test + @EnabledOnCommand("ZDIFFSTORE") // Redis 6.2 + void zdiffstore() { + String zset1 = "zset1"; + String zset2 = "zset2"; + + assertThat(redis.zadd(zset1, 1.0, "one")).isEqualTo(1); + assertThat(redis.zadd(zset1, 2.0, "two")).isEqualTo(1); + assertThat(redis.zadd(zset1, 3.0, "three")).isEqualTo(1); + assertThat(redis.zadd(zset2, 1.0, "one")).isEqualTo(1); + assertThat(redis.zadd(zset2, 2.0, "two")).isEqualTo(1); + + assertThat(redis.zdiffstore("out", zset1, zset2)).isEqualTo(1); + assertThat(redis.zrangeWithScores("out", 0, -1)).isEqualTo(svlist(sv(3.0, "three"))); + } + @Test void zincrby() { assertThat(redis.zincrby(key, 0.0, "a")).isEqualTo(0, offset(0.1));