未验证 提交 617e6a2d 编写于 作者: D Dragutin Marjanović 提交者: GitHub

Add 'WithScore' option both to 'zRank' and 'zRevRank' commands (#824)

上级 640b9a2c
version: '3.3'
services:
redis-cluster:
image: 'redis:6.2.7-alpine'
image: redis:7.2-rc1-alpine
container_name: redis-cluster
volumes:
- ./redis-cluster.sh:/data/redis-cluster.sh
......
......@@ -3,12 +3,12 @@ version: "3.2"
services:
redis1:
container_name: test_redis_1
image: redis:6.2.7-alpine
image: redis:7.2-rc1-alpine
ports:
- "6379:6379"
redis2:
container_name: test_redis_2
image: redis:6.2.7-alpine
image: redis:7.2-rc1-alpine
ports:
- "6380:6379"
......@@ -337,6 +337,22 @@ object Input {
RespCommand(RespCommandArgument.Literal(data.asString))
}
case object LcsQueryTypeInput extends Input[LcsQueryType] {
def encode(data: LcsQueryType): RespCommand = data match {
case LcsQueryType.Len => RespCommand(RespCommandArgument.Literal("LEN"))
case LcsQueryType.Idx(minMatchLength, withMatchLength) =>
val idx = Chunk.single(RespCommandArgument.Literal("IDX"))
val min =
if (minMatchLength > 1)
Chunk(RespCommandArgument.Literal("MINMATCHLEN"), RespCommandArgument.Value(minMatchLength.toString))
else Chunk.empty[RespCommandArgument]
val length =
if (withMatchLength) Chunk.single(RespCommandArgument.Literal("WITHMATCHLEN"))
else Chunk.empty[RespCommandArgument]
RespCommand(Chunk(idx, min, length).flatten)
}
}
case object LimitInput extends Input[Limit] {
def encode(data: Limit): RespCommand =
RespCommand(
......@@ -458,22 +474,6 @@ object Input {
RespCommand(RespCommandArgument.Literal("STORE"), RespCommandArgument.Value(data.key))
}
case object StrAlgoLcsQueryTypeInput extends Input[StrAlgoLcsQueryType] {
def encode(data: StrAlgoLcsQueryType): RespCommand = data match {
case StrAlgoLcsQueryType.Len => RespCommand(RespCommandArgument.Literal("LEN"))
case StrAlgoLcsQueryType.Idx(minMatchLength, withMatchLength) =>
val idx = Chunk.single(RespCommandArgument.Literal("IDX"))
val min =
if (minMatchLength > 1)
Chunk(RespCommandArgument.Literal("MINMATCHLEN"), RespCommandArgument.Value(minMatchLength.toString))
else Chunk.empty[RespCommandArgument]
val length =
if (withMatchLength) Chunk.single(RespCommandArgument.Literal("WITHMATCHLEN"))
else Chunk.empty[RespCommandArgument]
RespCommand(Chunk(idx, min, length).flatten)
}
}
case object StreamMaxLenInput extends Input[StreamMaxLen] {
def encode(data: StreamMaxLen): RespCommand = {
val chunk =
......@@ -670,6 +670,11 @@ object Input {
RespCommand(RespCommandArgument.Literal(data.asString))
}
case object WithScoreInput extends Input[WithScore] {
def encode(data: WithScore): RespCommand =
RespCommand(RespCommandArgument.Literal(data.asString))
}
case object WithScoresInput extends Input[WithScores] {
def encode(data: WithScores): RespCommand =
RespCommand(RespCommandArgument.Literal(data.asString))
......
......@@ -409,11 +409,11 @@ object Output {
}
}
case object StrAlgoLcsOutput extends Output[LcsOutput] {
protected def tryDecode(respValue: RespValue): LcsOutput =
case object LcsOutput extends Output[Lcs] {
protected def tryDecode(respValue: RespValue): Lcs =
respValue match {
case result @ RespValue.BulkString(_) => LcsOutput.Lcs(result.asString)
case RespValue.Integer(length) => LcsOutput.Length(length)
case result @ RespValue.BulkString(_) => Lcs.PlainLcs(result.asString)
case RespValue.Integer(length) => Lcs.Length(length)
case RespValue.ArrayValues(
RespValue.BulkString(_),
RespValue.Array(items),
......@@ -435,7 +435,7 @@ object Output {
Match(matchIdxs(0), matchIdxs(1), matchLength)
case other => throw ProtocolError(s"$other isn't a valid response")
}
LcsOutput.Matches(matches.toList, length)
Lcs.Matches(matches.toList, length)
case other => throw ProtocolError(s"$other isn't a valid set response")
}
}
......
......@@ -50,7 +50,7 @@ trait SortedSets extends RedisEnvironment {
def returning[M: Schema]: IO[RedisError, Option[(K, MemberScore[M])]] = {
val memberScoreOutput =
Tuple3Output(ArbitraryOutput[K](), ArbitraryOutput[M](), DoubleOutput).map { case (k, m, s) =>
(k, MemberScore(s, m))
(k, MemberScore(m, s))
}
val command = RedisCommand(
BzPopMax,
......@@ -85,7 +85,7 @@ trait SortedSets extends RedisEnvironment {
def returning[M: Schema]: IO[RedisError, Option[(K, MemberScore[M])]] = {
val memberScoreOutput =
Tuple3Output(ArbitraryOutput[K](), ArbitraryOutput[M](), DoubleOutput).map { case (k, m, s) =>
(k, MemberScore(s, m))
(k, MemberScore(m, s))
}
val command = RedisCommand(
BzPopMin,
......@@ -245,13 +245,13 @@ trait SortedSets extends RedisEnvironment {
Tuple3(
IntInput,
NonEmptyList(ArbitraryKeyInput[K]()),
ArbitraryValueInput[String]()
WithScoresInput
),
ChunkTuple2Output(ArbitraryOutput[M](), DoubleOutput)
.map(_.map { case (m, s) => MemberScore(s, m) }),
.map(_.map { case (m, s) => MemberScore(m, s) }),
executor
)
command.run((keys.size + 1, (key, keys.toList), WithScores.asString))
command.run((keys.size + 1, (key, keys.toList), WithScores))
}
}
......@@ -366,13 +366,13 @@ trait SortedSets extends RedisEnvironment {
NonEmptyList(ArbitraryKeyInput[K]()),
OptionalInput(AggregateInput),
OptionalInput(WeightsInput),
ArbitraryValueInput[String]()
WithScoresInput
),
ChunkTuple2Output(ArbitraryOutput[M](), DoubleOutput)
.map(_.map { case (m, s) => MemberScore(s, m) }),
.map(_.map { case (m, s) => MemberScore(m, s) }),
executor
)
command.run((keys.size + 1, (key, keys.toList), aggregate, weights, WithScores.asString))
command.run((keys.size + 1, (key, keys.toList), aggregate, weights, WithScores))
}
}
......@@ -468,7 +468,7 @@ trait SortedSets extends RedisEnvironment {
ZPopMax,
Tuple2(ArbitraryKeyInput[K](), OptionalInput(LongInput)),
ChunkTuple2Output(ArbitraryOutput[M](), DoubleOutput)
.map(_.map { case (m, s) => MemberScore(s, m) }),
.map(_.map { case (m, s) => MemberScore(m, s) }),
executor
)
command.run((key, count))
......@@ -494,7 +494,7 @@ trait SortedSets extends RedisEnvironment {
ZPopMin,
Tuple2(ArbitraryKeyInput[K](), OptionalInput(LongInput)),
ChunkTuple2Output(ArbitraryOutput[M](), DoubleOutput)
.map(_.map { case (m, s) => MemberScore(s, m) }),
.map(_.map { case (m, s) => MemberScore(m, s) }),
executor
)
command.run((key, count))
......@@ -558,13 +558,13 @@ trait SortedSets extends RedisEnvironment {
def returning[M: Schema]: IO[RedisError, Chunk[MemberScore[M]]] = {
val command = RedisCommand(
ZRandMember,
Tuple3(ArbitraryKeyInput[K](), LongInput, ArbitraryValueInput[String]()),
Tuple3(ArbitraryKeyInput[K](), LongInput, WithScoresInput),
ZRandMemberTuple2Output(ArbitraryOutput[M](), DoubleOutput)
.map(_.map { case (m, s) => MemberScore(s, m) }),
.map(_.map { case (m, s) => MemberScore(m, s) }),
executor
)
command.run((key, count, WithScores.asString))
command.run((key, count, WithScores))
}
}
......@@ -602,12 +602,12 @@ trait SortedSets extends RedisEnvironment {
def returning[M: Schema]: IO[RedisError, Chunk[MemberScore[M]]] = {
val command = RedisCommand(
ZRange,
Tuple3(ArbitraryKeyInput[K](), RangeInput, ArbitraryValueInput[String]()),
Tuple3(ArbitraryKeyInput[K](), RangeInput, WithScoresInput),
ChunkTuple2Output(ArbitraryOutput[M](), DoubleOutput)
.map(_.map { case (m, s) => MemberScore(s, m) }),
.map(_.map { case (m, s) => MemberScore(m, s) }),
executor
)
command.run((key, range, WithScores.asString))
command.run((key, range, WithScores))
}
}
......@@ -703,26 +703,26 @@ trait SortedSets extends RedisEnvironment {
ArbitraryKeyInput[K](),
ArbitraryValueInput[String](),
ArbitraryValueInput[String](),
ArbitraryValueInput[String](),
WithScoresInput,
OptionalInput(LimitInput)
),
ChunkTuple2Output(ArbitraryOutput[M](), DoubleOutput)
.map(_.map { case (m, s) => MemberScore(s, m) }),
.map(_.map { case (m, s) => MemberScore(m, s) }),
executor
)
command.run((key, scoreRange.min.asString, scoreRange.max.asString, WithScores.asString, limit))
command.run((key, scoreRange.min.asString, scoreRange.max.asString, WithScores, limit))
}
}
/**
* Determine the index of a member in a sorted set.
* Determine the index of a member in a sorted set, with scores ordered from low to high.
*
* @param key
* Key of a sorted set
* @param member
* Member of sorted set
* @return
* The rank of member in the sorted set stored at key, with the scores ordered from low to high.
* The rank of member in the sorted set stored at key.
*/
final def zRank[K: Schema, M: Schema](key: K, member: M): IO[RedisError, Option[Long]] = {
val command =
......@@ -735,6 +735,27 @@ trait SortedSets extends RedisEnvironment {
command.run((key, member))
}
/**
* Determine the index and score of a member in a sorted set, with scores ordered from low to high.
*
* @param key
* Key of a sorted set
* @param member
* Member of sorted set
* @return
* The rank of member along with the score in the sorted set stored at key.
*/
final def zRankWithScore[K: Schema, M: Schema](key: K, member: M): IO[RedisError, Option[RankScore]] = {
val command =
RedisCommand(
ZRank,
Tuple3(ArbitraryKeyInput[K](), ArbitraryValueInput[M](), WithScoreInput),
OptionalOutput(Tuple2Output(LongOutput, DoubleOutput).map { case (r, s) => RankScore(r, s) }),
executor
)
command.run((key, member, WithScore))
}
/**
* Remove one or more members from a sorted set.
*
......@@ -846,12 +867,12 @@ trait SortedSets extends RedisEnvironment {
def returning[M: Schema]: IO[RedisError, Chunk[MemberScore[M]]] = {
val command = RedisCommand(
ZRevRange,
Tuple3(ArbitraryKeyInput[K](), RangeInput, ArbitraryValueInput[String]()),
Tuple3(ArbitraryKeyInput[K](), RangeInput, WithScoresInput),
ChunkTuple2Output(ArbitraryOutput[M](), DoubleOutput)
.map(_.map { case (m, s) => MemberScore(s, m) }),
.map(_.map { case (m, s) => MemberScore(m, s) }),
executor
)
command.run((key, range, WithScores.asString))
command.run((key, range, WithScores))
}
}
......@@ -947,14 +968,14 @@ trait SortedSets extends RedisEnvironment {
ArbitraryKeyInput[K](),
ArbitraryValueInput[String](),
ArbitraryValueInput[String](),
ArbitraryValueInput[String](),
WithScoresInput,
OptionalInput(LimitInput)
),
ChunkTuple2Output(ArbitraryOutput[M](), DoubleOutput)
.map(_.map { case (m, s) => MemberScore(s, m) }),
.map(_.map { case (m, s) => MemberScore(m, s) }),
executor
)
command.run((key, scoreRange.max.asString, scoreRange.min.asString, WithScores.asString, limit))
command.run((key, scoreRange.max.asString, scoreRange.min.asString, WithScores, limit))
}
}
......@@ -966,7 +987,7 @@ trait SortedSets extends RedisEnvironment {
* @param member
* Member of sorted set
* @return
* The rank of member.
* The rank of member in the sorted set stored at key.
*/
final def zRevRank[K: Schema, M: Schema](key: K, member: M): IO[RedisError, Option[Long]] = {
val command = RedisCommand(
......@@ -978,6 +999,26 @@ trait SortedSets extends RedisEnvironment {
command.run((key, member))
}
/**
* Determine the index and score of a member in a sorted set, with scores ordered from high to low.
*
* @param key
* Key of a sorted set
* @param member
* Member of sorted set
* @return
* The rank of member along with the score in the sorted set stored at key.
*/
final def zRevRankWithScore[K: Schema, M: Schema](key: K, member: M): IO[RedisError, Option[RankScore]] = {
val command = RedisCommand(
ZRevRank,
Tuple3(ArbitraryKeyInput[K](), ArbitraryValueInput[M](), WithScoreInput),
OptionalOutput(Tuple2Output(LongOutput, DoubleOutput).map { case (r, s) => RankScore(r, s) }),
executor
)
command.run((key, member, WithScore))
}
/**
* Incrementally iterate sorted sets elements and associated scores.
*
......@@ -1001,7 +1042,7 @@ trait SortedSets extends RedisEnvironment {
new ResultBuilder1[({ type lambda[x] = (Long, MemberScores[x]) })#lambda] {
def returning[M: Schema]: IO[RedisError, (Long, Chunk[MemberScore[M]])] = {
val memberScoresOutput =
ChunkTuple2Output(ArbitraryOutput[M](), DoubleOutput).map(_.map { case (m, s) => MemberScore(s, m) })
ChunkTuple2Output(ArbitraryOutput[M](), DoubleOutput).map(_.map { case (m, s) => MemberScore(m, s) })
val command = RedisCommand(
ZScan,
Tuple4(ArbitraryKeyInput[K](), LongInput, OptionalInput(PatternInput), OptionalInput(CountInput)),
......@@ -1100,13 +1141,13 @@ trait SortedSets extends RedisEnvironment {
NonEmptyList(ArbitraryKeyInput[K]()),
OptionalInput(WeightsInput),
OptionalInput(AggregateInput),
ArbitraryValueInput[String]()
WithScoresInput
),
ChunkTuple2Output(ArbitraryOutput[M](), DoubleOutput)
.map(_.map { case (m, s) => MemberScore(s, m) }),
.map(_.map { case (m, s) => MemberScore(m, s) }),
executor
)
command.run((keys.size + 1, (key, keys.toList), weights, aggregate, WithScores.asString))
command.run((keys.size + 1, (key, keys.toList), weights, aggregate, WithScores))
}
}
......
......@@ -360,6 +360,35 @@ trait Strings extends RedisEnvironment {
command.run((key, increment))
}
/**
* Get the longest common subsequence of values stored in the given keys.
*
* @param keyA
* first value that will contain subsequence
* @param keyB
* second value that will contain subsequence
* @param lcsQueryType
* modifier that will affect the output
* @return
* Without modifiers returns the string representing the longest common substring. When LEN is given the command
* returns the length of the longest common substring. When IDX is given the command returns an array with the LCS
* length and all the ranges in both the strings, start and end offset for each string, where there are matches.
* When withMatchLen is given each array representing a match will also have the length of the match (see examples).
*/
final def lcs[K: Schema](keyA: K, keyB: K, lcsQueryType: Option[LcsQueryType] = None): IO[RedisError, Lcs] = {
val redisCommand = RedisCommand(
Lcs,
Tuple3(
ArbitraryKeyInput[K](),
ArbitraryKeyInput[K](),
OptionalInput(LcsQueryTypeInput)
),
LcsOutput,
executor
)
redisCommand.run((keyA, keyB, lcsQueryType))
}
/**
* Get all the values of the given keys.
*
......@@ -593,43 +622,6 @@ trait Strings extends RedisEnvironment {
command.run((key, offset, value))
}
/**
* Get the longest common subsequence of values stored in the given keys.
*
* @param command
* type of value it (possible values are Strings and Keys)
* @param keyA
* first value that will contain subsequence
* @param keyB
* second value that will contain subsequence
* @param lcsQueryType
* modifier that will affect the output
* @return
* Without modifiers returns the string representing the longest common substring. When LEN is given the command
* returns the length of the longest common substring. When IDX is given the command returns an array with the LCS
* length and all the ranges in both the strings, start and end offset for each string, where there are matches.
* When withMatchLen is given each array representing a match will also have the length of the match (see examples).
*/
final def strAlgoLcs[K: Schema](
command: StrAlgoLCS,
keyA: K,
keyB: K,
lcsQueryType: Option[StrAlgoLcsQueryType] = None
): IO[RedisError, LcsOutput] = {
val redisCommand = RedisCommand(
StrAlgoLcs,
Tuple4(
ArbitraryValueInput[String](),
ArbitraryKeyInput[K](),
ArbitraryKeyInput[K](),
OptionalInput(StrAlgoLcsQueryTypeInput)
),
StrAlgoLcsOutput,
executor
)
redisCommand.run((command.asString, keyA, keyB, lcsQueryType))
}
/**
* Get the length of a value stored in a key.
*
......@@ -661,6 +653,7 @@ private[redis] object Strings {
final val Incr = "INCR"
final val IncrBy = "INCRBY"
final val IncrByFloat = "INCRBYFLOAT"
final val Lcs = "LCS"
final val MGet = "MGET"
final val MSet = "MSET"
final val MSetNx = "MSETNX"
......@@ -670,6 +663,5 @@ private[redis] object Strings {
final val SetEx = "SETEX"
final val SetNx = "SETNX"
final val SetRange = "SETRANGE"
final val StrAlgoLcs = "STRALGO LCS"
final val StrLen = "STRLEN"
}
......@@ -78,10 +78,12 @@ trait SortedSets {
sealed case class LexRange(min: LexMinimum, max: LexMaximum)
sealed case class MemberScore[+M](score: Double, member: M)
sealed case class MemberScore[+M](member: M, score: Double)
type MemberScores[+M] = Chunk[MemberScore[M]]
sealed case class RankScore(rank: Long, score: Double)
sealed trait ScoreMaximum { self =>
private[redis] final def asString: String =
self match {
......@@ -114,6 +116,12 @@ trait SortedSets {
sealed case class ScoreRange(min: ScoreMinimum, max: ScoreMaximum)
case object WithScore {
private[redis] def asString: String = "WITHSCORE"
}
type WithScore = WithScore.type
case object WithScores {
private[redis] def asString: String = "WITHSCORES"
}
......
......@@ -17,32 +17,20 @@
package zio.redis.options
trait Strings {
sealed trait StrAlgoLCS { self =>
private[redis] final def asString: String =
self match {
case StralgoLCS.Strings => "STRINGS"
case StralgoLCS.Keys => "KEYS"
}
}
object StralgoLCS {
case object Strings extends StrAlgoLCS
case object Keys extends StrAlgoLCS
}
sealed trait StrAlgoLcsQueryType
sealed trait Lcs
object StrAlgoLcsQueryType {
case object Len extends StrAlgoLcsQueryType
case class Idx(minMatchLength: Int = 1, withMatchLength: Boolean = false) extends StrAlgoLcsQueryType
object Lcs {
case class PlainLcs(lcs: String) extends Lcs
case class Length(length: Long) extends Lcs
case class Matches(matches: List[Match], length: Long) extends Lcs
}
sealed trait LcsOutput
sealed trait LcsQueryType
object LcsOutput {
case class Lcs(lcs: String) extends LcsOutput
case class Length(length: Long) extends LcsOutput
case class Matches(matches: List[Match], length: Long) extends LcsOutput
object LcsQueryType {
case object Len extends LcsQueryType
case class Idx(minMatchLength: Int = 1, withMatchLength: Boolean = false) extends LcsQueryType
}
case class MatchIdx(start: Long, end: Long)
......
......@@ -16,7 +16,7 @@ object InputSpec extends BaseSpec {
import BitOperation._
import Order._
import RadiusUnit._
import StrAlgoLcsQueryType._
import LcsQueryType._
def spec: Spec[Any, Throwable] =
suite("Input encoders")(
......@@ -89,29 +89,29 @@ object InputSpec extends BaseSpec {
} yield assert(result)(equalTo(RespCommand(Literal("0"))))
}
),
suite("Stralgocommand")(
suite("LcsQueryType")(
test("length option") {
assert(StrAlgoLcsQueryTypeInput.encode(StrAlgoLcsQueryType.Len))(
assert(LcsQueryTypeInput.encode(LcsQueryType.Len))(
equalTo(RespCommand(Literal("LEN")))
)
},
test("idx option default") {
assert(StrAlgoLcsQueryTypeInput.encode(Idx()))(
assert(LcsQueryTypeInput.encode(Idx()))(
equalTo(RespCommand(Literal("IDX")))
)
},
test("idx option with minmatchlength") {
assert(StrAlgoLcsQueryTypeInput.encode(Idx(minMatchLength = 2)))(
assert(LcsQueryTypeInput.encode(Idx(minMatchLength = 2)))(
equalTo(RespCommand(Literal("IDX"), Literal("MINMATCHLEN"), Value("2")))
)
},
test("idx option with withmatchlength") {
assert(StrAlgoLcsQueryTypeInput.encode(Idx(withMatchLength = true)))(
assert(LcsQueryTypeInput.encode(Idx(withMatchLength = true)))(
equalTo(RespCommand(Literal("IDX"), Literal("WITHMATCHLEN")))
)
},
test("idx option with minmatchlength and withmatchlength") {
assert(StrAlgoLcsQueryTypeInput.encode(Idx(minMatchLength = 2, withMatchLength = true)))(
assert(LcsQueryTypeInput.encode(Idx(minMatchLength = 2, withMatchLength = true)))(
equalTo(RespCommand(Literal("IDX"), Literal("MINMATCHLEN"), Value("2"), Literal("WITHMATCHLEN")))
)
}
......@@ -628,32 +628,32 @@ object InputSpec extends BaseSpec {
suite("MemberScore")(
test("with positive score and empty member") {
for {
result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore(4.2d, "")))
result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore("", 4.2d)))
} yield assert(result)(equalTo(RespCommand(Value("4.2"), Value(""))))
},
test("with negative score and empty member") {
for {
result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore(-4.2d, "")))
result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore("", -4.2d)))
} yield assert(result)(equalTo(RespCommand(Value("-4.2"), Value(""))))
},
test("with zero score and empty member") {
for {
result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore(0d, "")))
result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore("", 0d)))
} yield assert(result)(equalTo(RespCommand(Value("0.0"), Value(""))))
},
test("with positive score and non-empty member") {
for {
result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore(4.2d, "member")))
result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore("member", 4.2d)))
} yield assert(result)(equalTo(RespCommand(Value("4.2"), Value("member"))))
},
test("with negative score and non-empty member") {
for {
result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore(-4.2d, "member")))
result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore("member", -4.2d)))
} yield assert(result)(equalTo(RespCommand(Value("-4.2"), Value("member"))))
},
test("with zero score and non-empty member") {
for {
result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore(0d, "member")))
result <- ZIO.attempt(MemberScoreInput[String]().encode(MemberScore("member", 0d)))
} yield assert(result)(equalTo(RespCommand(Value("0.0"), Value("member"))))
}
),
......@@ -1118,6 +1118,13 @@ object InputSpec extends BaseSpec {
} yield assert(result.args)(isEmpty)
}
),
suite("WithScore")(
test("valid value") {
for {
result <- ZIO.attempt(WithScoreInput.encode(WithScore))
} yield assert(result)(equalTo(RespCommand(Literal("WITHSCORE"))))
}
),
suite("WithScores")(
test("valid value") {
for {
......
......@@ -377,7 +377,7 @@ trait KeysSpec extends BaseSpec {
redis <- ZIO.service[Redis]
key <- uuid
value <- uuid
_ <- redis.zAdd(key)(MemberScore(1d, value))
_ <- redis.zAdd(key)(MemberScore(value, 1d))
zset <- redis.typeOf(key)
} yield assert(zset)(equalTo(RedisType.SortedSet))
},
......
......@@ -317,15 +317,8 @@ trait StringsSpec extends BaseSpec {
} yield assert(result)(equalTo(Chunk(Some(97L), Some(100L), Some(100L))))
}
),
suite("Stralgo")(
test("get LCS from 2 strings") {
val str1 = "foo"
val str2 = "fao"
assertZIO(ZIO.serviceWithZIO[Redis](_.strAlgoLcs(StralgoLCS.Strings, str1, str2)))(
equalTo(LcsOutput.Lcs("fo"))
)
},
test("get LCS from 2 keys") {
suite("LCS")(
test("get LCS from two keys") {
val str1 = "foo"
val str2 = "fao"
......@@ -335,8 +328,8 @@ trait StringsSpec extends BaseSpec {
_ <- redis.set(key1, str1, None, None, None)
key2 <- uuid
_ <- redis.set(key2, str2, None, None, None)
result <- redis.strAlgoLcs(StralgoLCS.Keys, key1, key2)
} yield assert(result)(equalTo(LcsOutput.Lcs("fo")))
result <- redis.lcs(key1, key2)
} yield assert(result)(equalTo(Lcs.PlainLcs("fo")))
},
test("get LCS from unknown keys") {
val str1 = "foo"
......@@ -348,19 +341,10 @@ trait StringsSpec extends BaseSpec {
_ <- redis.set(key1, str1, None, None, None)
key2 <- uuid
_ <- redis.set(key2, str2, None, None, None)
result <- redis.strAlgoLcs(StralgoLCS.Keys, "unknown", "unknown")
} yield assert(result)(equalTo(LcsOutput.Lcs("")))
result <- redis.lcs("unknown", "unknown")
} yield assert(result)(equalTo(Lcs.PlainLcs("")))
},
test("Get length of LCS for strings") {
val str1 = "foo"
val str2 = "fao"
assertZIO(
ZIO.serviceWithZIO[Redis](_.strAlgoLcs(StralgoLCS.Strings, str1, str2, Some(StrAlgoLcsQueryType.Len)))
)(
equalTo(LcsOutput.Length(2))
)
},
test("get length of LCS for keys") {
test("get length of LCS") {
val str1 = "foo"
val str2 = "fao"
......@@ -370,45 +354,23 @@ trait StringsSpec extends BaseSpec {
_ <- redis.set(key1, str1, None, None, None)
key2 <- uuid
_ <- redis.set(key2, str2, None, None, None)
result <- redis.strAlgoLcs(StralgoLCS.Keys, key1, key2, Some(StrAlgoLcsQueryType.Len))
} yield assert(result)(equalTo(LcsOutput.Length(2)))
result <- redis.lcs(key1, key2, Some(LcsQueryType.Len))
} yield assert(result)(equalTo(Lcs.Length(2)))
},
test("get length of LCS for unknown keys") {
val str1 = "foo"
val str2 = "fao"
for {
redis <- ZIO.service[Redis]
key1 <- uuid
_ <- redis.set(key1, str1, None, None, None)
key2 <- uuid
_ <- redis.set(key2, str2, None, None, None)
result <- redis.strAlgoLcs(
StralgoLCS.Keys,
"unknown",
"unknown",
Some(StrAlgoLcsQueryType.Len)
)
} yield assert(result)(equalTo(LcsOutput.Length(0)))
},
test("get index of LCS for strings") {
val str1 = "ohmytext"
val str2 = "mynewtext"
assertZIO(
ZIO.serviceWithZIO[Redis](_.strAlgoLcs(StralgoLCS.Strings, str1, str2, Some(StrAlgoLcsQueryType.Idx())))
)(
equalTo(
LcsOutput.Matches(
List(
Match(matchIdxA = MatchIdx(4, 7), matchIdxB = MatchIdx(5, 8)),
Match(matchIdxA = MatchIdx(2, 3), matchIdxB = MatchIdx(0, 1))
),
6
)
)
)
redis <- ZIO.service[Redis]
key1 <- uuid
_ <- redis.set(key1, str1, None, None, None)
key2 <- uuid
_ <- redis.set(key2, str2, None, None, None)
result <- redis.lcs("unknown", "unknown", Some(LcsQueryType.Len))
} yield assert(result)(equalTo(Lcs.Length(0)))
},
test("get index of LCS for keys") {
test("get index of LCS") {
val str1 = "!ohmytext"
val str2 = "!mynewtext"
......@@ -418,11 +380,11 @@ trait StringsSpec extends BaseSpec {
_ <- redis.set(key1, str1)
key2 <- uuid
_ <- redis.set(key2, str2)
result <- redis.strAlgoLcs(StralgoLCS.Keys, key1, key2, Some(StrAlgoLcsQueryType.Idx()))
result <- redis.lcs(key1, key2, Some(LcsQueryType.Idx()))
} yield {
assert(result)(
equalTo(
LcsOutput.Matches(
Lcs.Matches(
List(
Match(matchIdxA = MatchIdx(5, 8), matchIdxB = MatchIdx(6, 9)),
Match(matchIdxA = MatchIdx(3, 4), matchIdxB = MatchIdx(1, 2)),
......@@ -434,26 +396,21 @@ trait StringsSpec extends BaseSpec {
)
}
},
test("get index of LCS for keys with MINMATCHLEN") {
test("get index of LCS with MINMATCHLEN") {
val str1 = "!ohmytext"
val str2 = "!mynewtext"
for {
redis <- ZIO.service[Redis]
key1 <- uuid
_ <- redis.set(key1, str1)
key2 <- uuid
_ <- redis.set(key2, str2)
result <- redis.strAlgoLcs(
StralgoLCS.Keys,
key1,
key2,
Some(StrAlgoLcsQueryType.Idx(minMatchLength = 2))
)
redis <- ZIO.service[Redis]
key1 <- uuid
_ <- redis.set(key1, str1)
key2 <- uuid
_ <- redis.set(key2, str2)
result <- redis.lcs(key1, key2, Some(LcsQueryType.Idx(minMatchLength = 2)))
} yield {
assert(result)(
equalTo(
LcsOutput.Matches(
Lcs.Matches(
List(
Match(matchIdxA = MatchIdx(5, 8), matchIdxB = MatchIdx(6, 9)),
Match(matchIdxA = MatchIdx(3, 4), matchIdxB = MatchIdx(1, 2))
......@@ -464,26 +421,21 @@ trait StringsSpec extends BaseSpec {
)
}
},
test("get index of LCS for keys with WITHMATCHLEN") {
test("get index of LCS with WITHMATCHLEN") {
val str1 = "!ohmytext"
val str2 = "!mynewtext"
for {
redis <- ZIO.service[Redis]
key1 <- uuid
_ <- redis.set(key1, str1)
key2 <- uuid
_ <- redis.set(key2, str2)
result <- redis.strAlgoLcs(
StralgoLCS.Keys,
key1,
key2,
Some(StrAlgoLcsQueryType.Idx(withMatchLength = true))
)
redis <- ZIO.service[Redis]
key1 <- uuid
_ <- redis.set(key1, str1)
key2 <- uuid
_ <- redis.set(key2, str2)
result <- redis.lcs(key1, key2, Some(LcsQueryType.Idx(withMatchLength = true)))
} yield {
assert(result)(
equalTo(
LcsOutput.Matches(
Lcs.Matches(
List(
Match(matchIdxA = MatchIdx(5, 8), matchIdxB = MatchIdx(6, 9), matchLength = Some(4)),
Match(matchIdxA = MatchIdx(3, 4), matchIdxB = MatchIdx(1, 2), matchLength = Some(2)),
......@@ -495,26 +447,21 @@ trait StringsSpec extends BaseSpec {
)
}
},
test("get index of LCS for keys with MINMATCHLEN and WITHMATCHLEN") {
test("get index of LCS both with MINMATCHLEN and WITHMATCHLEN") {
val str1 = "!ohmytext"
val str2 = "!mynewtext"
for {
redis <- ZIO.service[Redis]
key1 <- uuid
_ <- redis.set(key1, str1)
key2 <- uuid
_ <- redis.set(key2, str2)
result <- redis.strAlgoLcs(
StralgoLCS.Keys,
key1,
key2,
Some(StrAlgoLcsQueryType.Idx(minMatchLength = 2, withMatchLength = true))
)
redis <- ZIO.service[Redis]
key1 <- uuid
_ <- redis.set(key1, str1)
key2 <- uuid
_ <- redis.set(key2, str2)
result <- redis.lcs(key1, key2, Some(LcsQueryType.Idx(minMatchLength = 2, withMatchLength = true)))
} yield {
assert(result)(
equalTo(
LcsOutput.Matches(
Lcs.Matches(
List(
Match(matchIdxA = MatchIdx(5, 8), matchIdxB = MatchIdx(6, 9), matchLength = Some(4)),
Match(matchIdxA = MatchIdx(3, 4), matchIdxB = MatchIdx(1, 2), matchLength = Some(2))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册