Copilot commented on code in PR #3296:
URL: https://github.com/apache/kvrocks/pull/3296#discussion_r2617785299
##########
tests/gocase/unit/type/tdigest/tdigest_test.go:
##########
@@ -716,4 +747,231 @@ func tdigestTests(t *testing.T, configs
util.KvrocksServerConfigs) {
require.EqualValues(t, expected[i], rank, "REVRANK
mismatch at index %d", i)
}
})
+
+ t.Run("tdigest.byrank and tdigest.byrevrank on empty sketch", func(t
*testing.T) {
+ key := "tdigest_byrank_on_empty_sketch"
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.CREATE", key,
"compression", "100").Err())
+
+ // Test BYRANK on empty sketch
+ rsp := rdb.Do(ctx, "TDIGEST.BYRANK", key, "1", "2", "4", "5",
"0", "1", "20")
+ require.NoError(t, rsp.Err())
+ vals, err := rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 7)
+ isRESP3 := configs["resp3-enabled"] == "yes"
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ require.True(t, math.IsNaN(rank), "expected NaN
but got %v at index %d", rank, i)
+ }
+ } else {
+ expected := []string{"nan", "nan", "nan", "nan", "nan",
"nan", "nan"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.EqualValues(t, expected[i], rank, "RANK
mismatch at index %d", i)
+ }
+ }
+
+ // Test BYREVRANK on empty sketch
+ rsp = rdb.Do(ctx, "TDIGEST.BYREVRANK", key, "1", "2", "4", "5",
"0", "1", "20")
+ require.NoError(t, rsp.Err())
+ vals, err = rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 7)
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ require.True(t, math.IsNaN(rank), "expected NaN
but got %v at index %d", rank, i)
+ }
+ } else {
+ expected := []string{"nan", "nan", "nan", "nan", "nan",
"nan", "nan"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.EqualValues(t, expected[i], rank,
"REVRANK mismatch at index %d", i)
+ }
+ }
+ })
+
+ t.Run("tdigest.byrank and tdigest.byrevrank on non-empty sketch",
func(t *testing.T) {
+ key := "tdigest_byrank_non_empty"
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.CREATE", key,
"compression", "100").Err())
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.ADD", key, "1", "2",
"3", "4", "5").Err())
+ isRESP3 := configs["resp3-enabled"] == "yes"
+
+ rsp := rdb.Do(ctx, "TDIGEST.BYRANK", key, "0", "1", "2", "3",
"4", "5", "6")
+ require.NoError(t, rsp.Err())
+ vals, err := rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 7)
+ if isRESP3 {
+ // Expected: rank 0 -> 1, rank 1 -> 2, rank 2 -> 3,
rank 3 -> 4, rank 4 -> 5
+ // Expected: rank 5, 6 -> out of range (+inf)
+ expected := []float64{1, 2, 3, 4, 5, math.Inf(1),
math.Inf(1)}
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ if math.IsInf(expected[i], 1) {
+ require.True(t, math.IsInf(rank, 1),
"expected +Inf but got %v at index %d", rank, i)
+ } else {
+ require.InDelta(t, expected[i], rank,
0.1, "BYRANK mismatch at index %d", i)
+ }
+ }
+ } else {
+ expectedStrings := []string{"1", "2", "3", "4", "5",
"inf", "inf"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.Equal(t, expectedStrings[i], rank,
"BYRANK mismatch at index %d", i)
+ }
+ }
+
+ rsp = rdb.Do(ctx, "TDIGEST.BYREVRANK", key, "0", "1", "2", "3",
"4", "5", "6")
+ require.NoError(t, rsp.Err())
+ vals, err = rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 7)
+
+ if isRESP3 {
+ // Expected: rank 0 -> 5, rank 1 -> 4, rank 2 -> 3,
rank 3 -> 2, rank 4 -> 1
+ // Expected: rank 5, 6 -> out of range (-inf)
+ expected := []float64{5, 4, 3, 2, 1, math.Inf(-1),
math.Inf(-1)}
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ if math.IsInf(expected[i], -1) {
+ require.True(t, math.IsInf(rank, -1),
"expected -Inf but got %v at index %d", rank, i)
+ } else {
+ require.InDelta(t, expected[i], rank,
0.1, "BYREVRANK mismatch at index %d", i)
+ }
+ }
+ } else {
+ expectedStrings := []string{"5", "4", "3", "2", "1",
"-inf", "-inf"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.Equal(t, expectedStrings[i], rank,
"BYREVRANK mismatch at index %d", i)
+ }
+ }
+ })
+
+ t.Run("tdigest.byrank and tdigest.byrevrank with duplicate values",
func(t *testing.T) {
+ key := "tdigest_byrank_duplicates"
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.CREATE", key,
"compression", "100").Err())
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.ADD", key, "1", "2",
"2", "3", "3", "3").Err())
+ isRESP3 := configs["resp3-enabled"] == "yes"
+
+ rsp := rdb.Do(ctx, "TDIGEST.BYRANK", key, "0", "1", "2", "3",
"4", "5", "6", "7")
+ require.NoError(t, rsp.Err())
+ vals, err := rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 8)
+ // test BYRANK with duplicate values
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ expected := []float64{1, 2, 2, 3, 3, 3}
+ if i < 6 {
+ require.InDelta(t, expected[i], rank,
0.1, "BYRANK mismatch at index %d", i)
+ } else {
+ require.True(t, math.IsInf(rank, 1),
"rank %d should be +Inf, got %v", i, rank)
+ }
+ }
+ } else {
+ expectedStrings := []string{"1", "2", "2", "3", "3",
"3", "inf", "inf"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.Equal(t, expectedStrings[i], rank,
"BYRANK mismatch at index %d", i)
+ }
+ }
+
+ // test BYREVRANK with duplicate values
+ rsp = rdb.Do(ctx, "TDIGEST.BYREVRANK", key, "0", "1", "2", "3",
"4", "5", "6", "7")
+ require.NoError(t, rsp.Err())
+ vals, err = rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 8)
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ expected := []float64{3, 3, 3, 2, 2, 1}
+ if i < 6 {
+ require.InDelta(t, expected[i], rank,
0.1, "BYREVRANK mismatch at index %d", i)
+ } else {
+ require.True(t, math.IsInf(rank, -1),
"rank %d should be +Inf, got %v", i, rank)
+ }
+ }
+ } else {
+ expectedStrings := []string{"3", "3", "3", "2", "2",
"1", "-inf", "-inf"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.Equal(t, expectedStrings[i], rank,
"BYREVRANK mismatch at index %d", i)
+ }
+ }
+ })
+
+ t.Run("tdigest.byrank and tdigest.byrevrank with duplicate values",
func(t *testing.T) {
Review Comment:
There are two test functions with the same name "tdigest.byrank and
tdigest.byrevrank with duplicate values" (lines 861 and 920). The second one
should have a different name, such as "tdigest.byrank and tdigest.byrevrank
with unordered duplicate values" to match the key name used in the test.
```suggestion
t.Run("tdigest.byrank and tdigest.byrevrank with unordered duplicate
values", func(t *testing.T) {
```
##########
tests/gocase/unit/type/tdigest/tdigest_test.go:
##########
@@ -716,4 +747,231 @@ func tdigestTests(t *testing.T, configs
util.KvrocksServerConfigs) {
require.EqualValues(t, expected[i], rank, "REVRANK
mismatch at index %d", i)
}
})
+
+ t.Run("tdigest.byrank and tdigest.byrevrank on empty sketch", func(t
*testing.T) {
+ key := "tdigest_byrank_on_empty_sketch"
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.CREATE", key,
"compression", "100").Err())
+
+ // Test BYRANK on empty sketch
+ rsp := rdb.Do(ctx, "TDIGEST.BYRANK", key, "1", "2", "4", "5",
"0", "1", "20")
+ require.NoError(t, rsp.Err())
+ vals, err := rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 7)
+ isRESP3 := configs["resp3-enabled"] == "yes"
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ require.True(t, math.IsNaN(rank), "expected NaN
but got %v at index %d", rank, i)
+ }
+ } else {
+ expected := []string{"nan", "nan", "nan", "nan", "nan",
"nan", "nan"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.EqualValues(t, expected[i], rank, "RANK
mismatch at index %d", i)
+ }
+ }
+
+ // Test BYREVRANK on empty sketch
+ rsp = rdb.Do(ctx, "TDIGEST.BYREVRANK", key, "1", "2", "4", "5",
"0", "1", "20")
+ require.NoError(t, rsp.Err())
+ vals, err = rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 7)
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ require.True(t, math.IsNaN(rank), "expected NaN
but got %v at index %d", rank, i)
+ }
+ } else {
+ expected := []string{"nan", "nan", "nan", "nan", "nan",
"nan", "nan"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.EqualValues(t, expected[i], rank,
"REVRANK mismatch at index %d", i)
+ }
+ }
+ })
+
+ t.Run("tdigest.byrank and tdigest.byrevrank on non-empty sketch",
func(t *testing.T) {
+ key := "tdigest_byrank_non_empty"
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.CREATE", key,
"compression", "100").Err())
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.ADD", key, "1", "2",
"3", "4", "5").Err())
+ isRESP3 := configs["resp3-enabled"] == "yes"
+
+ rsp := rdb.Do(ctx, "TDIGEST.BYRANK", key, "0", "1", "2", "3",
"4", "5", "6")
+ require.NoError(t, rsp.Err())
+ vals, err := rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 7)
+ if isRESP3 {
+ // Expected: rank 0 -> 1, rank 1 -> 2, rank 2 -> 3,
rank 3 -> 4, rank 4 -> 5
+ // Expected: rank 5, 6 -> out of range (+inf)
+ expected := []float64{1, 2, 3, 4, 5, math.Inf(1),
math.Inf(1)}
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ if math.IsInf(expected[i], 1) {
+ require.True(t, math.IsInf(rank, 1),
"expected +Inf but got %v at index %d", rank, i)
+ } else {
+ require.InDelta(t, expected[i], rank,
0.1, "BYRANK mismatch at index %d", i)
+ }
+ }
+ } else {
+ expectedStrings := []string{"1", "2", "3", "4", "5",
"inf", "inf"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.Equal(t, expectedStrings[i], rank,
"BYRANK mismatch at index %d", i)
+ }
+ }
+
+ rsp = rdb.Do(ctx, "TDIGEST.BYREVRANK", key, "0", "1", "2", "3",
"4", "5", "6")
+ require.NoError(t, rsp.Err())
+ vals, err = rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 7)
+
+ if isRESP3 {
+ // Expected: rank 0 -> 5, rank 1 -> 4, rank 2 -> 3,
rank 3 -> 2, rank 4 -> 1
+ // Expected: rank 5, 6 -> out of range (-inf)
+ expected := []float64{5, 4, 3, 2, 1, math.Inf(-1),
math.Inf(-1)}
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ if math.IsInf(expected[i], -1) {
+ require.True(t, math.IsInf(rank, -1),
"expected -Inf but got %v at index %d", rank, i)
+ } else {
+ require.InDelta(t, expected[i], rank,
0.1, "BYREVRANK mismatch at index %d", i)
+ }
+ }
+ } else {
+ expectedStrings := []string{"5", "4", "3", "2", "1",
"-inf", "-inf"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.Equal(t, expectedStrings[i], rank,
"BYREVRANK mismatch at index %d", i)
+ }
+ }
+ })
+
+ t.Run("tdigest.byrank and tdigest.byrevrank with duplicate values",
func(t *testing.T) {
+ key := "tdigest_byrank_duplicates"
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.CREATE", key,
"compression", "100").Err())
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.ADD", key, "1", "2",
"2", "3", "3", "3").Err())
+ isRESP3 := configs["resp3-enabled"] == "yes"
+
+ rsp := rdb.Do(ctx, "TDIGEST.BYRANK", key, "0", "1", "2", "3",
"4", "5", "6", "7")
+ require.NoError(t, rsp.Err())
+ vals, err := rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 8)
+ // test BYRANK with duplicate values
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ expected := []float64{1, 2, 2, 3, 3, 3}
+ if i < 6 {
+ require.InDelta(t, expected[i], rank,
0.1, "BYRANK mismatch at index %d", i)
+ } else {
+ require.True(t, math.IsInf(rank, 1),
"rank %d should be +Inf, got %v", i, rank)
+ }
+ }
+ } else {
+ expectedStrings := []string{"1", "2", "2", "3", "3",
"3", "inf", "inf"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.Equal(t, expectedStrings[i], rank,
"BYRANK mismatch at index %d", i)
+ }
+ }
+
+ // test BYREVRANK with duplicate values
+ rsp = rdb.Do(ctx, "TDIGEST.BYREVRANK", key, "0", "1", "2", "3",
"4", "5", "6", "7")
+ require.NoError(t, rsp.Err())
+ vals, err = rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 8)
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ expected := []float64{3, 3, 3, 2, 2, 1}
+ if i < 6 {
+ require.InDelta(t, expected[i], rank,
0.1, "BYREVRANK mismatch at index %d", i)
+ } else {
+ require.True(t, math.IsInf(rank, -1),
"rank %d should be +Inf, got %v", i, rank)
Review Comment:
The comment says "rank %d should be +Inf" but the actual check is for
negative infinity (math.IsInf(rank, -1)). The comment should say "rank %d
should be -Inf" to match the actual test logic.
```suggestion
require.True(t, math.IsInf(rank, -1),
"rank %d should be -Inf, got %v", i, rank)
```
##########
src/commands/error_constants.h:
##########
@@ -53,4 +53,5 @@ inline constexpr const char *errKeyAlreadyExists = "key
already exists";
inline constexpr const char *errParsingNumkeys = "error parsing numkeys";
inline constexpr const char *errNumkeysMustBePositive = "numkeys need to be a
positive integer";
inline constexpr const char *errWrongKeyword = "wrong keyword";
+inline constexpr const char *errInvalidRankValue = "rank needs to be non
negative";
Review Comment:
The error message "rank needs to be non negative" should be "rank needs to
be non-negative" (with a hyphen). The compound adjective "non-negative"
requires a hyphen when used before a noun.
```suggestion
inline constexpr const char *errInvalidRankValue = "rank needs to be
non-negative";
```
##########
tests/gocase/unit/type/tdigest/tdigest_test.go:
##########
@@ -716,4 +747,231 @@ func tdigestTests(t *testing.T, configs
util.KvrocksServerConfigs) {
require.EqualValues(t, expected[i], rank, "REVRANK
mismatch at index %d", i)
}
})
+
+ t.Run("tdigest.byrank and tdigest.byrevrank on empty sketch", func(t
*testing.T) {
+ key := "tdigest_byrank_on_empty_sketch"
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.CREATE", key,
"compression", "100").Err())
+
+ // Test BYRANK on empty sketch
+ rsp := rdb.Do(ctx, "TDIGEST.BYRANK", key, "1", "2", "4", "5",
"0", "1", "20")
+ require.NoError(t, rsp.Err())
+ vals, err := rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 7)
+ isRESP3 := configs["resp3-enabled"] == "yes"
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ require.True(t, math.IsNaN(rank), "expected NaN
but got %v at index %d", rank, i)
+ }
+ } else {
+ expected := []string{"nan", "nan", "nan", "nan", "nan",
"nan", "nan"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.EqualValues(t, expected[i], rank, "RANK
mismatch at index %d", i)
+ }
+ }
+
+ // Test BYREVRANK on empty sketch
+ rsp = rdb.Do(ctx, "TDIGEST.BYREVRANK", key, "1", "2", "4", "5",
"0", "1", "20")
+ require.NoError(t, rsp.Err())
+ vals, err = rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 7)
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ require.True(t, math.IsNaN(rank), "expected NaN
but got %v at index %d", rank, i)
+ }
+ } else {
+ expected := []string{"nan", "nan", "nan", "nan", "nan",
"nan", "nan"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.EqualValues(t, expected[i], rank,
"REVRANK mismatch at index %d", i)
+ }
+ }
+ })
+
+ t.Run("tdigest.byrank and tdigest.byrevrank on non-empty sketch",
func(t *testing.T) {
+ key := "tdigest_byrank_non_empty"
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.CREATE", key,
"compression", "100").Err())
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.ADD", key, "1", "2",
"3", "4", "5").Err())
+ isRESP3 := configs["resp3-enabled"] == "yes"
+
+ rsp := rdb.Do(ctx, "TDIGEST.BYRANK", key, "0", "1", "2", "3",
"4", "5", "6")
+ require.NoError(t, rsp.Err())
+ vals, err := rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 7)
+ if isRESP3 {
+ // Expected: rank 0 -> 1, rank 1 -> 2, rank 2 -> 3,
rank 3 -> 4, rank 4 -> 5
+ // Expected: rank 5, 6 -> out of range (+inf)
+ expected := []float64{1, 2, 3, 4, 5, math.Inf(1),
math.Inf(1)}
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ if math.IsInf(expected[i], 1) {
+ require.True(t, math.IsInf(rank, 1),
"expected +Inf but got %v at index %d", rank, i)
+ } else {
+ require.InDelta(t, expected[i], rank,
0.1, "BYRANK mismatch at index %d", i)
+ }
+ }
+ } else {
+ expectedStrings := []string{"1", "2", "3", "4", "5",
"inf", "inf"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.Equal(t, expectedStrings[i], rank,
"BYRANK mismatch at index %d", i)
+ }
+ }
+
+ rsp = rdb.Do(ctx, "TDIGEST.BYREVRANK", key, "0", "1", "2", "3",
"4", "5", "6")
+ require.NoError(t, rsp.Err())
+ vals, err = rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 7)
+
+ if isRESP3 {
+ // Expected: rank 0 -> 5, rank 1 -> 4, rank 2 -> 3,
rank 3 -> 2, rank 4 -> 1
+ // Expected: rank 5, 6 -> out of range (-inf)
+ expected := []float64{5, 4, 3, 2, 1, math.Inf(-1),
math.Inf(-1)}
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ if math.IsInf(expected[i], -1) {
+ require.True(t, math.IsInf(rank, -1),
"expected -Inf but got %v at index %d", rank, i)
+ } else {
+ require.InDelta(t, expected[i], rank,
0.1, "BYREVRANK mismatch at index %d", i)
+ }
+ }
+ } else {
+ expectedStrings := []string{"5", "4", "3", "2", "1",
"-inf", "-inf"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.Equal(t, expectedStrings[i], rank,
"BYREVRANK mismatch at index %d", i)
+ }
+ }
+ })
+
+ t.Run("tdigest.byrank and tdigest.byrevrank with duplicate values",
func(t *testing.T) {
+ key := "tdigest_byrank_duplicates"
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.CREATE", key,
"compression", "100").Err())
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.ADD", key, "1", "2",
"2", "3", "3", "3").Err())
+ isRESP3 := configs["resp3-enabled"] == "yes"
+
+ rsp := rdb.Do(ctx, "TDIGEST.BYRANK", key, "0", "1", "2", "3",
"4", "5", "6", "7")
+ require.NoError(t, rsp.Err())
+ vals, err := rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 8)
+ // test BYRANK with duplicate values
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ expected := []float64{1, 2, 2, 3, 3, 3}
+ if i < 6 {
+ require.InDelta(t, expected[i], rank,
0.1, "BYRANK mismatch at index %d", i)
+ } else {
+ require.True(t, math.IsInf(rank, 1),
"rank %d should be +Inf, got %v", i, rank)
+ }
+ }
+ } else {
+ expectedStrings := []string{"1", "2", "2", "3", "3",
"3", "inf", "inf"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.Equal(t, expectedStrings[i], rank,
"BYRANK mismatch at index %d", i)
+ }
+ }
+
+ // test BYREVRANK with duplicate values
+ rsp = rdb.Do(ctx, "TDIGEST.BYREVRANK", key, "0", "1", "2", "3",
"4", "5", "6", "7")
+ require.NoError(t, rsp.Err())
+ vals, err = rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 8)
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ expected := []float64{3, 3, 3, 2, 2, 1}
+ if i < 6 {
+ require.InDelta(t, expected[i], rank,
0.1, "BYREVRANK mismatch at index %d", i)
+ } else {
+ require.True(t, math.IsInf(rank, -1),
"rank %d should be +Inf, got %v", i, rank)
+ }
+ }
+ } else {
+ expectedStrings := []string{"3", "3", "3", "2", "2",
"1", "-inf", "-inf"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.Equal(t, expectedStrings[i], rank,
"BYREVRANK mismatch at index %d", i)
+ }
+ }
+ })
+
+ t.Run("tdigest.byrank and tdigest.byrevrank with duplicate values",
func(t *testing.T) {
+ key := "tdigest_byrank_unordered_dup_"
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.CREATE", key,
"compression", "100").Err())
+ require.NoError(t, rdb.Do(ctx, "TDIGEST.ADD", key, "12", "100",
"50", "36", "75", "81", "35.5", "46", "36", "8.8", "15", "4", "32.5", "12",
"8.8", "7", "99", "1").Err())
+ isRESP3 := configs["resp3-enabled"] == "yes"
+
+ rsp := rdb.Do(ctx, "TDIGEST.BYRANK", key, "0", "1", "2", "3",
"4", "5", "6", "7", "7", "5", "20", "100")
+ require.NoError(t, rsp.Err())
+ vals, err := rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 12)
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ expected := []float64{1, 4, 7, 8.8, 8.8, 12,
12, 15, 15, 12}
+ if i < 10 {
+ require.InDelta(t, expected[i], rank,
0.1, "BYRANK mismatch at index %d", i)
+ } else {
+ require.True(t, math.IsInf(rank, 1),
"rank %d should be +Inf, got %v", i, rank)
+ }
+ }
+ } else {
+ expectedStrings := []string{"1", "4", "7", "8.8",
"8.8", "12", "12", "15", "15", "12", "inf", "inf"}
+ for i, v := range vals {
+ rank, ok := v.(string)
+ require.True(t, ok, "expected string but got %T
at index %d", v, i)
+ require.Equal(t, expectedStrings[i], rank,
"BYRANK mismatch at index %d", i)
+ }
+ }
+
+ // test BYREVRANK with duplicate values
+ rsp = rdb.Do(ctx, "TDIGEST.BYREVRANK", key, "20", "75", "0",
"1", "2", "3", "4", "5", "6", "7")
+ require.NoError(t, rsp.Err())
+ vals, err = rsp.Slice()
+ require.NoError(t, err)
+ require.Len(t, vals, 10)
+ if isRESP3 {
+ for i, v := range vals {
+ rank, ok := v.(float64)
+ require.True(t, ok, "expected float64 but got
%T at index %d", v, i)
+ expected := []float64{0, 0, 100, 99, 81, 75,
50, 46, 36, 36}
+ if i < 2 {
+ require.True(t, math.IsInf(rank, -1),
"rank %d should be +Inf, got %v", i, rank)
Review Comment:
The comment says "rank %d should be +Inf" but the actual check is for
negative infinity (math.IsInf(rank, -1)). The comment should say "rank %d
should be -Inf" to match the actual test logic.
```suggestion
require.True(t, math.IsInf(rank, -1),
"rank %d should be -Inf, got %v", i, rank)
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]