mirror of
https://github.com/redis/redis.git
synced 2026-05-28 04:02:46 -04:00
Align SUNIONCARD LIMIT 0 semantics with SINTERCARD convention
SINTERCARD treats LIMIT 0 as "no limit" while SUNIONCARD was returning 0 immediately. Align the behavior so LIMIT 0 means "no limit" for both commands. Remove the have_limit flag and early return, and change the APPROX path checks from have_limit to limit > 0.
This commit is contained in:
parent
19cadde9ee
commit
e2cc2b3e09
2 changed files with 10 additions and 16 deletions
13
src/t_set.c
13
src/t_set.c
|
|
@ -1859,8 +1859,7 @@ void sunionCommand(client *c) {
|
|||
void sunioncardCommand(client *c) {
|
||||
long j;
|
||||
long numkeys = 0;
|
||||
long limit = 0;
|
||||
int have_limit = 0;
|
||||
long limit = 0; /* 0 means no limit. */
|
||||
int approx = 0;
|
||||
|
||||
if (getRangeLongFromObjectOrReply(c, c->argv[1], 1, LONG_MAX,
|
||||
|
|
@ -1880,7 +1879,6 @@ void sunioncardCommand(client *c) {
|
|||
if (getPositiveLongFromObjectOrReply(c, c->argv[j], &limit,
|
||||
"LIMIT can't be negative") != C_OK)
|
||||
return;
|
||||
have_limit = 1;
|
||||
} else if (!strcasecmp(opt, "APPROX")) {
|
||||
approx = 1;
|
||||
} else {
|
||||
|
|
@ -1889,11 +1887,6 @@ void sunioncardCommand(client *c) {
|
|||
}
|
||||
}
|
||||
|
||||
if (have_limit && limit == 0) {
|
||||
addReplyLongLong(c, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (approx) {
|
||||
/* HLL-based approximate cardinality: use a temporary HLL object
|
||||
* with the standard sparse→dense encoding (same as PFADD). */
|
||||
|
|
@ -1938,7 +1931,7 @@ void sunioncardCommand(client *c) {
|
|||
}
|
||||
|
||||
elements_processed++;
|
||||
if (have_limit &&
|
||||
if (limit > 0 &&
|
||||
(elements_processed % HLL_APPROX_CHECK_INTERVAL == 0)) {
|
||||
uint64_t est = hllCount(hllobj->ptr, NULL);
|
||||
if (est >= (uint64_t)limit) {
|
||||
|
|
@ -1951,7 +1944,7 @@ void sunioncardCommand(client *c) {
|
|||
}
|
||||
|
||||
uint64_t cardinality = hllCount(hllobj->ptr, NULL);
|
||||
if (have_limit && cardinality > (uint64_t)limit)
|
||||
if (limit > 0 && cardinality > (uint64_t)limit)
|
||||
cardinality = (uint64_t)limit;
|
||||
|
||||
if (server.memory_tracking_enabled) {
|
||||
|
|
|
|||
|
|
@ -306,11 +306,11 @@ foreach type {single multiple single_multiple} {
|
|||
assert_equal $exact $approx
|
||||
}
|
||||
|
||||
test "SUNIONCARD LIMIT 0 returns 0 immediately" {
|
||||
test "SUNIONCARD LIMIT 0 means no limit" {
|
||||
r del set1{t} set2{t}
|
||||
r sadd set1{t} a b c
|
||||
r sadd set2{t} c d e
|
||||
assert_equal 0 [r sunioncard 2 set1{t} set2{t} LIMIT 0]
|
||||
assert_equal 5 [r sunioncard 2 set1{t} set2{t} LIMIT 0]
|
||||
}
|
||||
|
||||
test "SUNIONCARD with both APPROX and LIMIT" {
|
||||
|
|
@ -318,7 +318,7 @@ foreach type {single multiple single_multiple} {
|
|||
r sadd set1{t} a b c
|
||||
r sadd set2{t} c d e
|
||||
assert_equal 3 [r sunioncard 2 set1{t} set2{t} APPROX LIMIT 3]
|
||||
assert_equal 0 [r sunioncard 2 set1{t} set2{t} APPROX LIMIT 0]
|
||||
assert_equal 5 [r sunioncard 2 set1{t} set2{t} APPROX LIMIT 0]
|
||||
}
|
||||
|
||||
test "SUNIONCARD APPROX with large sets is within HLL error margin" {
|
||||
|
|
@ -421,7 +421,7 @@ foreach type {single multiple single_multiple} {
|
|||
test "SUNIONCARD with two sets - $type" {
|
||||
set expected [llength [lsort -uniq "[r smembers set1{t}] [r smembers set2{t}]"]]
|
||||
assert_equal $expected [r sunioncard 2 set1{t} set2{t}]
|
||||
assert_equal 0 [r sunioncard 2 set1{t} set2{t} LIMIT 0]
|
||||
assert_equal $expected [r sunioncard 2 set1{t} set2{t} LIMIT 0]
|
||||
assert_equal 3 [r sunioncard 2 set1{t} set2{t} LIMIT 3]
|
||||
assert_equal $expected [r sunioncard 2 set1{t} set2{t} LIMIT 10000]
|
||||
}
|
||||
|
|
@ -429,7 +429,7 @@ foreach type {single multiple single_multiple} {
|
|||
test "SUNIONCARD against three sets - $type" {
|
||||
set expected [llength [lsort -uniq "[r smembers set1{t}] [r smembers set2{t}] [r smembers set3{t}]"]]
|
||||
assert_equal $expected [r sunioncard 3 set1{t} set2{t} set3{t}]
|
||||
assert_equal 0 [r sunioncard 3 set1{t} set2{t} set3{t} LIMIT 0]
|
||||
assert_equal $expected [r sunioncard 3 set1{t} set2{t} set3{t} LIMIT 0]
|
||||
assert_equal 2 [r sunioncard 3 set1{t} set2{t} set3{t} LIMIT 2]
|
||||
assert_equal $expected [r sunioncard 3 set1{t} set2{t} set3{t} LIMIT 10000]
|
||||
}
|
||||
|
|
@ -447,7 +447,8 @@ foreach type {single multiple single_multiple} {
|
|||
}
|
||||
|
||||
test "SUNIONCARD APPROX with LIMIT - $type" {
|
||||
assert_equal 0 [r sunioncard 2 set1{t} set2{t} APPROX LIMIT 0]
|
||||
set approx_no_limit [r sunioncard 2 set1{t} set2{t} APPROX]
|
||||
assert_equal $approx_no_limit [r sunioncard 2 set1{t} set2{t} APPROX LIMIT 0]
|
||||
assert_equal 10 [r sunioncard 2 set1{t} set2{t} APPROX LIMIT 10]
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue