Skip to content
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

Implement zRandMember #369

Merged
merged 5 commits into from
May 6, 2021
Merged
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
55 changes: 54 additions & 1 deletion redis/src/main/scala/zio/redis/api/SortedSets.scala
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ trait SortedSets {
*
* @param key Key of the set
* @param keys Keys of the rest sets
* @return list of scores or None associated with the specified member values (a double precision floating point
* @return List of scores or None associated with the specified member values (a double precision floating point
* number).
*/
final def zMScore[K: Schema](
Expand All @@ -802,6 +802,58 @@ trait SortedSets {
val command = RedisCommand(Zmscore, NonEmptyList(ArbitraryInput[K]()), ChunkOutput(OptionalOutput(DoubleOutput)))
command.run((key, keys.toList))
}

/**
* Return a random element from the sorted set value stored at key.
*
* @param key Key of a sorted set
* @return Return a random element from the sorted set value stored at key.
*/
final def zRandMember[K: Schema, M: Schema](key: K): ZIO[RedisExecutor, RedisError, Option[M]] = {
val command = RedisCommand(ZRandMember, ArbitraryInput[K](), OptionalOutput(ArbitraryOutput[M]()))
command.run(key)
}

/**
* Return random elements from the sorted set value stored at key.
*
* @param key Key of a sorted set
* @param count If the provided count argument is positive, return an array of distinct elements.
* The array's length is either count or the sorted set's cardinality (ZCARD), whichever is lower
* @return Return an array of elements from the sorted set value stored at key.
*/
final def zRandMember[K: Schema, M: Schema](key: K, count: Long): ZIO[RedisExecutor, RedisError, Option[Chunk[M]]] = {
val command = RedisCommand(
ZRandMember,
Tuple2(ArbitraryInput[K](), LongInput),
OptionalOutput(ChunkOutput(ArbitraryOutput[M]()))
)
command.run((key, count))
}

/**
* Return random elements from the sorted set value stored at key.
*
* @param key Key of a sorted set
* @param count If the provided count argument is positive, return an array of distinct elements.
* The array's length is either count or the sorted set's cardinality (ZCARD), whichever is lower
* @return When the additional count argument is passed, the command returns an array of elements, or an empty array when key does not exist.
* If the WITHSCORES modifier is used, the reply is a list elements and their scores from the sorted set.
*/
final def zRandMemberWithScores[K: Schema, M: Schema](
key: K,
count: Long
): ZIO[RedisExecutor, RedisError, Option[Chunk[MemberScore[M]]]] = {
val command = RedisCommand(
ZRandMember,
Tuple3(ArbitraryInput[K](), LongInput, ArbitraryInput[String]()),
OptionalOutput(
ChunkTuple2Output(ArbitraryOutput[M](), DoubleOutput)
.map(_.map { case (m, s) => MemberScore(s, m) })
)
)
command.run((key, count, WithScores.stringify))
}
}

private[redis] object SortedSets {
Expand Down Expand Up @@ -834,4 +886,5 @@ private[redis] object SortedSets {
final val ZUnion = "ZUNION"
final val ZUnionStore = "ZUNIONSTORE"
final val Zmscore = "ZMSCORE"
final val ZRandMember = "ZRANDMEMBER"
}
49 changes: 49 additions & 0 deletions redis/src/test/scala/zio/redis/SortedSetsSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1667,6 +1667,55 @@ trait SortedSetsSpec extends BaseSpec {
card <- zUnionStore(dest, 2, first, second)(Some(::(2, List(3))), Some(Aggregate.Max))
} yield assert(card)(equalTo(4L))
}
),
suite("zRandMember")(
testM("key does not exist") {
for {
first <- uuid
notExists <- uuid
_ <- zAdd(first)(MemberScore(1d, "a"), MemberScore(2d, "b"), MemberScore(3d, "c"), MemberScore(4d, "d"))
ret <- zRandMember[String, String](notExists)
} yield assert(ret)(isNone)
},
testM("key does not exist with count") {
for {
first <- uuid
notExists <- uuid
_ <- zAdd(first)(MemberScore(1d, "a"), MemberScore(2d, "b"), MemberScore(3d, "c"), MemberScore(4d, "d"))
ret <- zRandMember[String, String](notExists, 1)
} yield assert(ret)(isNone)
},
testM("get an element") {
for {
first <- uuid
_ <- zAdd(first)(MemberScore(1d, "a"), MemberScore(2d, "b"), MemberScore(3d, "c"), MemberScore(4d, "d"))
ret <- zRandMember[String, String](first)
} yield assert(ret)(isSome)
},
testM("get elements with count") {
for {
first <- uuid
_ <- zAdd(first)(MemberScore(1d, "a"), MemberScore(2d, "b"), MemberScore(3d, "c"), MemberScore(4d, "d"))
ret <- zRandMember[String, String](first, 2)
} yield assert(ret)(isSome) && assert(ret.get.size)(equalTo(2))
}
),
suite("zRandMemberWithScores")(
testM("key does not exist") {
for {
first <- uuid
notExists <- uuid
_ <- zAdd(first)(MemberScore(1d, "a"), MemberScore(2d, "b"), MemberScore(3d, "c"), MemberScore(4d, "d"))
ret <- zRandMemberWithScores[String, String](notExists, 1)
} yield assert(ret)(isNone)
},
testM("get elements with count") {
for {
first <- uuid
_ <- zAdd(first)(MemberScore(1d, "a"), MemberScore(2d, "b"), MemberScore(3d, "c"), MemberScore(4d, "d"))
ret <- zRandMemberWithScores[String, String](first, 2)
} yield assert(ret)(isSome) && assert(ret.get.size)(equalTo(2))
}
)
)

Expand Down