Unverified Commit 87131a5f authored by Lu JJ's avatar Lu JJ Committed by GitHub
Browse files

fast path when SDIFF command has the same key as the first key (#10663)



When user uses the same input key for SDIFF as the first one, the result must be empty, so we don't need to process the elements to test.

This method is like the one done in zset‘s `zsetChooseDiffAlgorithm`
Co-authored-by: default avatarOran Agra <oran@redislabs.com>
parent 9c39256a
...@@ -1055,6 +1055,7 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum, ...@@ -1055,6 +1055,7 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
sds ele; sds ele;
int j, cardinality = 0; int j, cardinality = 0;
int diff_algo = 1; int diff_algo = 1;
int sameset = 0;
for (j = 0; j < setnum; j++) { for (j = 0; j < setnum; j++) {
robj *setobj = lookupKeyRead(c->db, setkeys[j]); robj *setobj = lookupKeyRead(c->db, setkeys[j]);
...@@ -1067,6 +1068,9 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum, ...@@ -1067,6 +1068,9 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
return; return;
} }
sets[j] = setobj; sets[j] = setobj;
if (j > 0 && sets[0] == sets[j]) {
sameset = 1;
}
} }
/* Select what DIFF algorithm to use. /* Select what DIFF algorithm to use.
...@@ -1078,7 +1082,7 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum, ...@@ -1078,7 +1082,7 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
* the sets. * the sets.
* *
* We compute what is the best bet with the current input here. */ * We compute what is the best bet with the current input here. */
if (op == SET_OP_DIFF && sets[0]) { if (op == SET_OP_DIFF && sets[0] && !sameset) {
long long algo_one_work = 0, algo_two_work = 0; long long algo_one_work = 0, algo_two_work = 0;
for (j = 0; j < setnum; j++) { for (j = 0; j < setnum; j++) {
...@@ -1120,6 +1124,8 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum, ...@@ -1120,6 +1124,8 @@ void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
} }
setTypeReleaseIterator(si); setTypeReleaseIterator(si);
} }
} else if (op == SET_OP_DIFF && sameset) {
/* At least one of the sets is the same one (same key) as the first one, result must be empty. */
} else if (op == SET_OP_DIFF && sets[0] && diff_algo == 1) { } else if (op == SET_OP_DIFF && sets[0] && diff_algo == 1) {
/* DIFF Algorithm 1: /* DIFF Algorithm 1:
* *
......
...@@ -285,6 +285,13 @@ start_server { ...@@ -285,6 +285,13 @@ start_server {
} }
assert_equal {1 2 3 4} [lsort [r smembers setres{t}]] assert_equal {1 2 3 4} [lsort [r smembers setres{t}]]
} }
test "SINTER/SUNION/SDIFF with three same sets - $type" {
set expected [lsort "[r smembers set1{t}]"]
assert_equal $expected [lsort [r sinter set1{t} set1{t} set1{t}]]
assert_equal $expected [lsort [r sunion set1{t} set1{t} set1{t}]]
assert_equal {} [lsort [r sdiff set1{t} set1{t} set1{t}]]
}
} }
test "SDIFF with first set empty" { test "SDIFF with first set empty" {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment