Unverified Commit 991aff1c authored by Chen Tianjie's avatar Chen Tianjie Committed by GitHub
Browse files

Optimize KEYS when pattern includes hashtag and implies a single slot. (#12754)

in #12536 we made a similar optimization for SCAN, now that hashtags in
patterns. When we can make sure all keys matching the pettern will be in
the same slot, we can limit the iteration to run only one one.
parent 35c8d616
......@@ -33,6 +33,7 @@
#include "latency.h"
#include "script.h"
#include "functions.h"
#include "cluster.h"
#include <signal.h>
#include <ctype.h>
......@@ -993,13 +994,22 @@ void randomkeyCommand(client *c) {
void keysCommand(client *c) {
dictEntry *de;
sds pattern = c->argv[1]->ptr;
int plen = sdslen(pattern), allkeys;
int plen = sdslen(pattern), allkeys, pslot = -1;
long numkeys = 0;
void *replylen = addReplyDeferredLen(c);
dbIterator *dbit = dbIteratorInit(c->db, DB_MAIN);
allkeys = (pattern[0] == '*' && plen == 1);
if (!allkeys) {
pslot = patternHashSlot(pattern, plen);
}
dictIterator *di = NULL;
dbIterator *dbit = NULL;
if (server.cluster_enabled && !allkeys && pslot != -1) {
di = dictGetSafeIterator(c->db->dict[pslot]);
} else {
dbit = dbIteratorInit(c->db, DB_MAIN);
}
robj keyobj;
while ((de = dbIteratorNext(dbit)) != NULL) {
while ((de = di ? dictNext(di) : dbIteratorNext(dbit)) != NULL) {
sds key = dictGetKey(de);
if (allkeys || stringmatchlen(pattern,plen,key,sdslen(key),0)) {
......@@ -1012,7 +1022,10 @@ void keysCommand(client *c) {
if (c->flags & CLIENT_CLOSE_ASAP)
break;
}
dbReleaseIterator(dbit);
if (di)
dictReleaseIterator(di);
if (dbit)
dbReleaseIterator(dbit);
setDeferredArrayLen(c,replylen,numkeys);
}
......
......@@ -34,6 +34,14 @@ start_server {tags {"keyspace"}} {
r dbsize
} {6}
test {KEYS with hashtag} {
foreach key {"{a}x" "{a}y" "{a}z" "{b}a" "{b}b" "{b}c"} {
r set $key hello
}
assert_equal [lsort [r keys "{a}*"]] [list "{a}x" "{a}y" "{a}z"]
assert_equal [lsort [r keys "*{b}*"]] [list "{b}a" "{b}b" "{b}c"]
}
test {DEL all keys} {
foreach key [r keys *] {r del $key}
r dbsize
......
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