Skip to content

Commit 96ba194

Browse files
author
Roman Janusz
committed
redis: ZUNION
1 parent a67f510 commit 96ba194

File tree

2 files changed

+82
-10
lines changed

2 files changed

+82
-10
lines changed

commons-redis/src/main/scala/com/avsystem/commons/redis/commands/sortedSets.scala

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,38 @@ trait SortedSetsApi extends ApiSubset {
224224
def zscore(key: Key, member: Value): Result[Opt[Double]] =
225225
execute(new Zscore(key, member))
226226

227+
/** Executes [[http://redis.io/commands/zunion ZUNION]] */
228+
def zunion(key: Key, keys: Key*): Result[Seq[Value]] =
229+
zunion(key +:: keys)
230+
231+
/** Executes [[http://redis.io/commands/zunion ZUNION]] */
232+
def zunion(keys: Iterable[Key], aggregation: OptArg[Aggregation] = OptArg.Empty): Result[Seq[Value]] =
233+
execute(new Zunion(keys, Opt.Empty, aggregation.toOpt))
234+
235+
/** Executes [[http://redis.io/commands/zunion ZUNION]] */
236+
def zunionWeights(keyWeight: (Key, Double), keysWeights: (Key, Double)*): Result[Seq[Value]] =
237+
zunionWeights(keyWeight +:: keysWeights)
238+
239+
/** Executes [[http://redis.io/commands/zunion ZUNION]] */
240+
def zunionWeights(keysWeights: Iterable[(Key, Double)], aggregation: OptArg[Aggregation] = OptArg.Empty): Result[Seq[Value]] =
241+
execute(new Zunion(keysWeights.map(_._1), keysWeights.map(_._2).opt, aggregation.toOpt))
242+
243+
/** Executes [[http://redis.io/commands/zunion ZUNION]] */
244+
def zunionWithscores(key: Key, keys: Key*): Result[Seq[(Value, Double)]] =
245+
zunionWithscores(key +:: keys)
246+
247+
/** Executes [[http://redis.io/commands/zunion ZUNION]] */
248+
def zunionWithscores(keys: Iterable[Key], aggregation: OptArg[Aggregation] = OptArg.Empty): Result[Seq[(Value, Double)]] =
249+
execute(new ZunionWithscores(keys, Opt.Empty, aggregation.toOpt))
250+
251+
/** Executes [[http://redis.io/commands/zunion ZUNION]] */
252+
def zunionWeightsWithscores(keyWeight: (Key, Double), keysWeights: (Key, Double)*): Result[Seq[(Value, Double)]] =
253+
zunionWeightsWithscores(keyWeight +:: keysWeights)
254+
255+
/** Executes [[http://redis.io/commands/zunion ZUNION]] */
256+
def zunionWeightsWithscores(keysWeights: Iterable[(Key, Double)], aggregation: OptArg[Aggregation] = OptArg.Empty): Result[Seq[(Value, Double)]] =
257+
execute(new ZunionWithscores(keysWeights.map(_._1), keysWeights.map(_._2).opt, aggregation.toOpt))
258+
227259
/** Executes [[http://redis.io/commands/zunionstore ZUNIONSTORE]] */
228260
def zunionstore(destination: Key, key: Key, keys: Key*): Result[Long] = zunionstore(destination, key +:: keys)
229261

@@ -257,6 +289,9 @@ trait SortedSetsApi extends ApiSubset {
257289
def bzpopmin(keys: Iterable[Key], timeout: Int): Result[Opt[(Key, Value, Double)]] =
258290
execute(new Bzpopmin(keys, timeout))
259291

292+
private abstract class AbstractValuesWithScoresCommand
293+
extends AbstractRedisCommand[Seq[(Value, Double)]](flatMultiBulkAsPairSeq(bulkAs[Value], bulkAsDouble))
294+
260295
private abstract class AbstractZadd[T](decoder: ReplyDecoder[T])
261296
(key: Key, memberScores: IterableOnce[(Value, Double)], existence: Opt[Existence], changed: Boolean, incr: Boolean)
262297
extends AbstractRedisCommand[T](decoder) with NodeCommand {
@@ -289,8 +324,7 @@ trait SortedSetsApi extends ApiSubset {
289324
val encoded: Encoded = encoder("ZDIFFSTORE").key(destination).add(keys.size).keys(keys).result
290325
}
291326

292-
private final class ZdiffWithscores(keys: Iterable[Key])
293-
extends AbstractRedisCommand[Seq[(Value, Double)]](flatMultiBulkAsPairSeq(bulkAs[Value], bulkAsDouble)) with NodeCommand {
327+
private final class ZdiffWithscores(keys: Iterable[Key]) extends AbstractValuesWithScoresCommand with NodeCommand {
294328
val encoded: Encoded = encoder("ZDIFF").add(keys.size).keys(keys).add("WITHSCORES").result
295329
}
296330

@@ -311,7 +345,7 @@ trait SortedSetsApi extends ApiSubset {
311345
}
312346

313347
private final class ZinterWithscores(keys: Iterable[Key], weights: Opt[Iterable[Double]], aggregation: Opt[Aggregation])
314-
extends AbstractRedisCommand[Seq[(Value, Double)]](flatMultiBulkAsPairSeq(bulkAs[Value], bulkAsDouble)) with NodeCommand {
348+
extends AbstractValuesWithScoresCommand with NodeCommand {
315349
val encoded: Encoded = encoder("ZINTER").add(keys.size).keys(keys)
316350
.optAdd("WEIGHTS", weights).optAdd("AGGREGATE", aggregation).add("WITHSCORES").result
317351
}
@@ -328,12 +362,12 @@ trait SortedSetsApi extends ApiSubset {
328362
}
329363

330364
private final class Zpopmin(key: Key, count: Opt[Long])
331-
extends AbstractRedisCommand[Seq[(Value, Double)]](flatMultiBulkAsPairSeq(bulkAs[Value], bulkAsDouble)) with NodeCommand {
365+
extends AbstractValuesWithScoresCommand with NodeCommand {
332366
val encoded: Encoded = encoder("ZPOPMIN").key(key).optAdd(count).result
333367
}
334368

335369
private final class Zpopmax(key: Key, count: Opt[Long])
336-
extends AbstractRedisCommand[Seq[(Value, Double)]](flatMultiBulkAsPairSeq(bulkAs[Value], bulkAsDouble)) with NodeCommand {
370+
extends AbstractValuesWithScoresCommand with NodeCommand {
337371
val encoded: Encoded = encoder("ZPOPMAX").key(key).optAdd(count).result
338372
}
339373

@@ -420,12 +454,24 @@ trait SortedSetsApi extends ApiSubset {
420454
val encoded: Encoded = encoder("ZSCORE").key(key).data(member).result
421455
}
422456

457+
private final class Zunion(keys: Iterable[Key], weights: Opt[Iterable[Double]], aggregation: Opt[Aggregation])
458+
extends RedisDataSeqCommand[Value] with NodeCommand {
459+
val encoded: Encoded = encoder("ZUNION").add(keys.size).keys(keys)
460+
.optAdd("WEIGHTS", weights).optAdd("AGGREGATE", aggregation).result
461+
}
462+
423463
private final class Zunionstore(destination: Key, keys: Iterable[Key], weights: Opt[Iterable[Double]], aggregation: Opt[Aggregation])
424464
extends RedisLongCommand with NodeCommand {
425465
val encoded: Encoded = encoder("ZUNIONSTORE").key(destination).add(keys.size).keys(keys)
426466
.optAdd("WEIGHTS", weights).optAdd("AGGREGATE", aggregation).result
427467
}
428468

469+
private final class ZunionWithscores(keys: Iterable[Key], weights: Opt[Iterable[Double]], aggregation: Opt[Aggregation])
470+
extends AbstractValuesWithScoresCommand with NodeCommand {
471+
val encoded: Encoded = encoder("ZUNION").add(keys.size).keys(keys)
472+
.optAdd("WEIGHTS", weights).optAdd("AGGREGATE", aggregation).add("WITHSCORES").result
473+
}
474+
429475
private final class Bzpopmax(keys: Iterable[Key], timeout: Int)
430476
extends AbstractRedisCommand[Opt[(Key, Value, Double)]](multiBulkAsZTripleOf[Key, Value]) with NodeCommand {
431477
val encoded: Encoded = encoder("BZPOPMAX").keys(keys).add(timeout).result

commons-redis/src/test/scala/com/avsystem/commons/redis/commands/SortedSetsApiSuite.scala

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ trait SortedSetsApiSuite extends CommandsSuite {
6767
zadd("{key}1", "foo" -> 1.0, "bar" -> 2.0),
6868
zadd("{key}2", "bar" -> 3.0, "lol" -> 4.0)
6969
)
70-
zinter( "{key}1", "{key}2").assertEquals(Seq("bar"))
71-
zinterWithscores( "{key}1", "{key}2").assertEquals(Seq("bar" -> 5.0))
72-
zinterWithscores( Seq("{key}1", "{key}2"), Aggregation.Sum).assertEquals(Seq("bar" -> 5.0))
73-
zinterWithscores( Seq("{key}1", "{key}2"), Aggregation.Min).assertEquals(Seq("bar" -> 2.0))
74-
zinterWithscores( Seq("{key}1", "{key}2"), Aggregation.Max).assertEquals(Seq("bar" -> 3.0))
70+
zinter("{key}1", "{key}2").assertEquals(Seq("bar"))
71+
zinterWithscores("{key}1", "{key}2").assertEquals(Seq("bar" -> 5.0))
72+
zinterWithscores(Seq("{key}1", "{key}2"), Aggregation.Sum).assertEquals(Seq("bar" -> 5.0))
73+
zinterWithscores(Seq("{key}1", "{key}2"), Aggregation.Min).assertEquals(Seq("bar" -> 2.0))
74+
zinterWithscores(Seq("{key}1", "{key}2"), Aggregation.Max).assertEquals(Seq("bar" -> 3.0))
7575
}
7676

7777
apiTest("ZINTER with WEIGHTS") {
@@ -275,6 +275,32 @@ trait SortedSetsApiSuite extends CommandsSuite {
275275
zscore("key", "b").assertEquals(2.0.opt)
276276
}
277277

278+
apiTest("ZUNION") {
279+
setup(
280+
zadd("{key}1", "foo" -> 1.0, "bar" -> 2.0),
281+
zadd("{key}2", "bar" -> 3.0, "lol" -> 6.0)
282+
)
283+
zunion("{key}1", "{key}2").assertEquals(Seq("foo", "bar", "lol"))
284+
zunionWithscores("{key}1", "{key}2")
285+
.assertEquals(Seq("foo" -> 1.0, "bar" -> 5.0, "lol" -> 6.0))
286+
zunionWithscores(Seq("{key}1", "{key}2"), Aggregation.Sum)
287+
.assertEquals(Seq("foo" -> 1.0, "bar" -> 5.0, "lol" -> 6.0))
288+
zunionWithscores(Seq("{key}1", "{key}2"), Aggregation.Min)
289+
.assertEquals(Seq("foo" -> 1.0, "bar" -> 2.0, "lol" -> 6.0))
290+
zunionWithscores(Seq("{key}1", "{key}2"), Aggregation.Max)
291+
.assertEquals(Seq("foo" -> 1.0, "bar" -> 3.0, "lol" -> 6.0))
292+
}
293+
294+
apiTest("ZUNION with WEIGHTS") {
295+
setup(
296+
zadd("{key}1", "foo" -> 1.0, "bar" -> 2.0),
297+
zadd("{key}2", "bar" -> 3.0, "lol" -> 5.0)
298+
)
299+
zunionWeights("{key}1" -> 1.0, "{key}2" -> 2.0).assertEquals(Seq("foo", "bar", "lol"))
300+
zunionWeightsWithscores("{key}1" -> 1.0, "{key}2" -> 2.0)
301+
.assertEquals(Seq("foo" -> 1.0, "bar" -> 8.0, "lol" -> 10.0))
302+
}
303+
278304
apiTest("ZUNIONSTORE") {
279305
setup(
280306
zadd("{key}1", "foo" -> 1.0, "bar" -> 2.0),

0 commit comments

Comments
 (0)