Skip to content

Commit

Permalink
implement a bunch of sorted set commands, first pass.
Browse files Browse the repository at this point in the history
  • Loading branch information
John Loehrer committed Aug 11, 2024
1 parent 8d02fe4 commit 81bebb0
Show file tree
Hide file tree
Showing 5 changed files with 839 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,330 @@ import scala.concurrent.Future

import com.github.scoquelin.arugula.commands.RedisBaseAsyncCommands.{InitialCursor, ScanResults}

/**
* Asynchronous commands for manipulating/querying Sorted Sets
* @tparam K The key type
* @tparam V The value type
*/
trait RedisSortedSetAsyncCommands[K, V] {
import RedisSortedSetAsyncCommands._
def zAdd(key: K, args: Option[ZAddOptions], values: ScoreWithValue[V]*): Future[Long]

/**
* Add one or more members to a sorted set, or update its score if it already exists
* @param key The key
* @param values The values to add
* @return The number of elements added to the sorted set
*/
def zAdd(key: K, values: ScoreWithValue[V]*): Future[Long]

/**
* Add one or more members to a sorted set, or update its score if it already exists
* @param key The key
* @param args Optional arguments
* @param values The values to add
* @return The number of elements added to the sorted set
*/
def zAdd(key: K, args: ZAddOptions, values: ScoreWithValue[V]*): Future[Long]

/**
* Add one or more members to a sorted set, or update its score if it already exists
* @param key The key
* @return The number of members in the sorted set
*/
def zAddIncr(key: K, score: Double, member: V): Future[Option[Double]]

/**
* Add one or more members to a sorted set, or update its score if it already exists
* @param key
* @param values
* @return
*/
def zAddIncr(key: K, args: ZAddOptions, score: Double, member: V): Future[Option[Double]]

/**
* Get the number of members in a sorted set
* @param key The key
* @return The number of members in the sorted set
*/
def zCard(key: K): Future[Long]

/**
* Count the members in a sorted set with scores within the given values
* @param key The key
* @param range The range of scores
* @return The number of elements in the specified score range
*/
def zCount[T: Numeric](key: K, range: ZRange[T]): Future[Long]

/**
* Remove and return a member with the lowest score from a sorted set
* @param key The key
* @return The member with the lowest score, or None if the set is empty
*/
def zPopMin(key: K): Future[Option[ScoreWithValue[V]]]

/**
* Remove and return up to count members with the lowest scores in a sorted set
* @param key The key
* @param count The number of members to pop
* @return The members with the lowest scores
*/
def zPopMin(key: K, count: Long): Future[List[ScoreWithValue[V]]]

/**
* Remove and return a member with the highest score from a sorted set
* @param key The key
* @return The member with the highest score, or None if the set is empty
*/
def zPopMax(key: K): Future[Option[ScoreWithValue[V]]]

/**
* Remove and return up to count members with the highest scores in a sorted set
* @param key The key
* @param count The number of members to pop
* @return The members with the highest scores
*/
def zPopMax(key: K, count: Long): Future[List[ScoreWithValue[V]]]

/**
* Get the score of a member in a sorted set
* @param key The key
* @param value The value
* @return The score of the member, or None if the member does not exist
*/
def zScore(key: K, value: V): Future[Option[Double]]

/**
* Return a range of members in a sorted set, by index
* @param key The key
* @param start The start index
* @param stop The stop index
* @return The members in the specified range
*/
def zRange(key: K, start: Long, stop: Long): Future[List[V]]

/**
* Return a range of members with scores in a sorted set, by index.
* @param key The key
* @param start The start index
* @param stop The stop index
* @return The members with scores in the specified range
*/
def zRangeWithScores(key: K, start: Long, stop: Long): Future[List[ScoreWithValue[V]]]

/**
* Return a range of members in a sorted set, by score
* @param key The key
* @param range The range of scores
* @param limit Optional limit
* @return The members in the specified score range
*/
def zRangeByScore[T: Numeric](key: K, range: ZRange[T], limit: Option[RangeLimit]): Future[List[V]]

/**
* Return a range of members in a sorted set, by score, with scores ordered from high to low
* @param key The key
* @param range The range of scores
* @param limit Optional limit
* @return The members in the specified score range
*/
def zRangeByScoreWithScores[T: Numeric](key: K, range: ZRange[T], limit: Option[RangeLimit] = None): Future[List[ScoreWithValue[V]]]

/**
* Return a range of members in a sorted set, by score, with scores ordered from high to low
* @param key The key
* @param range The range of scores
* @param limit Optional limit
* @return The members in the specified score range
*/
def zRevRangeByScore[T: Numeric](key: K, range: ZRange[T], limit: Option[RangeLimit]): Future[List[V]]

/**
* Return a range of members in a sorted set, by score, with scores ordered from high to low
* @param key The key
* @param range The range of scores
* @param limit Optional limit
* @return The members in the specified score range
*/
def zRevRangeByScoreWithScores[T: Numeric](key: K, range: ZRange[T], limit: Option[RangeLimit] = None): Future[List[ScoreWithValue[V]]]

/**
* Increment the score of a member in a sorted set
* @param key The key
* @param amount The amount to increment by
* @param value The value
* @return The new score of the member
*/
def zIncrBy(key: K, amount: Double, value: V): Future[Double]

/**
* Determine the index of a member in a sorted set
* @param key The key
* @param value The value
* @return The index of the member, or None if the member does not exist
*/
def zRank(key: K, value: V): Future[Option[Long]]

/**
* Determine the index of a member in a sorted set, with the score
* @param key The key
* @param value The value
* @return The index of the member, or None if the member does not exist
*/
def zRankWithScore(key: K, value: V): Future[Option[ScoreWithValue[Long]]]

/**
* Determine the index of a member in a sorted set, with the score
* @param key The key
* @param value The value
* @return The index of the member, or None if the member does not exist
*/
def zRevRank(key: K, value: V): Future[Option[Long]]

/**
* Determine the index of a member in a sorted set, with the score
* @param key The key
* @param value The value
* @return The index of the member, or None if the member does not exist
*/
def zRevRankWithScore(key: K, value: V): Future[Option[ScoreWithValue[Long]]]

/**
* Scan a sorted set
* @param key The key
* @param cursor The cursor
* @param limit The maximum number of elements to return
* @param matchPattern The pattern to match
* @return The cursor and the values
*/
def zScan(key: K, cursor: String = InitialCursor, limit: Option[Long] = None, matchPattern: Option[String] = None): Future[ScanResults[List[ScoreWithValue[V]]]]

/**
* Get a random member from a sorted set
* @param key The key
* @return A random member from the sorted set, or None if the set is empty
*/
def zRandMember(key: K): Future[Option[V]]

/**
* Get multiple random members from a sorted set
* @param key The key
* @param count The number of members to get
* @return A list of random members from the sorted set
*/
def zRandMember(key: K, count: Long): Future[List[V]]

/**
* Get a random member from a sorted set, with the score
* @param key The key
* @return A random member from the sorted set, or None if the set is empty
*/
def zRandMemberWithScores(key: K): Future[Option[ScoreWithValue[V]]]

/**
* Get multiple random members from a sorted set, with the score
* @param key The key
* @param count The number of members to get
* @return A list of random members from the sorted set
*/
def zRandMemberWithScores(key: K, count: Long): Future[List[ScoreWithValue[V]]]

/**
* Remove one or more members from a sorted set
* @param key The key
* @param values The values to remove
* @return The number of members removed from the sorted set
*/
def zRem(key: K, values: V*): Future[Long]

/**
* Remove all members in a sorted set with scores between the given values
* @param key The key
* @param start The start score
* @param stop The stop score
* @return The number of members removed from the sorted set
*/
def zRemRangeByRank(key: K, start: Long, stop: Long): Future[Long]
def zRemRangeByScore[T: Numeric](key: K, range: ZRange[T]): Future[Long]
}

object RedisSortedSetAsyncCommands {
/**
* Remove all members in a sorted set with scores between the given values
* @param key The key
* @param range The range of scores
* @return The number of members removed from the sorted set
*/
def zRemRangeByScore[T: Numeric](key: K, range: ZRange[T]): Future[Long]

sealed trait ZAddOptions
object ZAddOptions {
case object NX extends ZAddOptions
/**
* Get the score of a member in a sorted set, with the score
* @param key The key
* @param start The start index
* @param stop The stop index
* @return The members with scores in the specified range
*/
def zRevRange(key: K, start: Long, stop: Long): Future[List[V]]

case object XX extends ZAddOptions
/**
* Get the score of a member in a sorted set, with the score
* @param key The key
* @param start The start index
* @param stop The stop index
* @return The members with scores in the specified range
*/
def zRevRangeWithScores(key: K, start: Long, stop: Long): Future[List[ScoreWithValue[V]]]
}

case object LT extends ZAddOptions
// TODO : Implement the following commands:
//bzmpop
//bzpopmin
//bzpopmax
//zaddincr
//zdiff
//zdiffstore
//zdiffWithScores
//zinter
//zintercard
//zinterWithScores
//zinterstore
//zlexcount
//zlexcount
//zmscore
//zmpop
//zrandmemberWithScores
//zrangebylex
//zrangestore
//zrangestorebylex
//zrangestorebyscore
//zremrangebylex
//zrevrangebylex
//zrevrangestore
//zrevrangestorebylex
//zrevrangestorebyscore
//zunion
//zunionWithScores
//zunionstore

case object GT extends ZAddOptions
/**
* Companion object for RedisSortedSetAsyncCommands
*/
object RedisSortedSetAsyncCommands {

case object CH extends ZAddOptions
}
/**
* Options for ZADD. These options are used to modify the behavior of the ZADD command.
* They can be combined to create the desired behavior.
* Note: The GT, LT and NX options are mutually exclusive in Redis.
* @param ch Option Modify the return value from the number of new elements added, to the total number of elements changed.
* @param nx Option to only add new elements
* @param xx Option to only update elements that already exist
* @param lt Option to only add elements with a score less than the given score
* @param gt Option to only add elements with a score greater than the given score
*/
case class ZAddOptions(
ch: Boolean = false,
nx: Boolean = false,
xx: Boolean = false,
lt: Boolean = false,
gt: Boolean = false,
)

final case class ScoreWithValue[V](score: Double, value: V)
final case class ZRange[T](start: T, end: T)
Expand Down
Loading

0 comments on commit 81bebb0

Please sign in to comment.