Skip to content

Commit

Permalink
improve performance for scan command when matching data type
Browse files Browse the repository at this point in the history
  • Loading branch information
judeng committed Jul 7, 2023
1 parent aefdc57 commit abafd80
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 35 deletions.
15 changes: 2 additions & 13 deletions src/db.c
Original file line number Diff line number Diff line change
Expand Up @@ -848,11 +848,10 @@ void scanCallback(void *privdata, const dictEntry *de) {
serverAssert(!((data->type != LLONG_MAX) && o));

/* Filter an element if it isn't the type we want. */
/* TODO: uncomment in redis 8.0
if (!o && data->type != LLONG_MAX) {
robj *rval = dictGetVal(de);
if (!objectTypeCompare(rval, data->type)) return;
}*/
}

/* Filter element if it does not match the pattern. */
sds keysds = dictGetKey(de);
Expand Down Expand Up @@ -1000,9 +999,8 @@ void scanGenericCommand(client *c, robj *o, unsigned long cursor) {
typename = c->argv[i+1]->ptr;
type = getObjectTypeByName(typename);
if (type == LLONG_MAX) {
/* TODO: uncomment in redis 8.0
addReplyErrorFormat(c, "unknown type name '%s'", typename);
return; */
return;
}
i+= 2;
} else {
Expand Down Expand Up @@ -1129,15 +1127,6 @@ void scanGenericCommand(client *c, robj *o, unsigned long cursor) {
while ((ln = listNext(&li))) {
sds key = listNodeValue(ln);
initStaticStringObject(kobj, key);
/* Filter an element if it isn't the type we want. */
/* TODO: remove this in redis 8.0 */
if (typename) {
robj* typecheck = lookupKeyReadWithFlags(c->db, &kobj, LOOKUP_NOTOUCH|LOOKUP_NONOTIFY);
if (!typecheck || !objectTypeCompare(typecheck, type)) {
listDelNode(keys, ln);
}
continue;
}
if (expireIfNeeded(c->db, &kobj, 0)) {
listDelNode(keys, ln);
}
Expand Down
25 changes: 3 additions & 22 deletions tests/unit/scan.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -109,25 +109,9 @@ start_server {tags {"scan network"}} {

after 2

# TODO: remove this in redis 8.0
set cur 0
set keys {}
while 1 {
set res [r scan $cur type "string1"]
set cur [lindex $res 0]
set k [lindex $res 1]
lappend keys {*}$k
if {$cur == 0} break
}

assert_equal 0 [llength $keys]
# make sure that expired key have been removed by scan command
assert_equal 1000 [scan [regexp -inline {keys\=([\d]*)} [r info keyspace]] keys=%d]

# TODO: uncomment in redis 8.0
#assert_error "*unknown type name*" {r scan 0 type "string1"}
assert_error "*unknown type name*" {r scan 0 type "string1"}
# expired key will be no touched by scan command
#assert_equal 1001 [scan [regexp -inline {keys\=([\d]*)} [r info keyspace]] keys=%d]
assert_equal 1001 [scan [regexp -inline {keys\=([\d]*)} [r info keyspace]] keys=%d]
r debug set-active-expire 1
} {OK} {needs:debug}

Expand Down Expand Up @@ -191,11 +175,8 @@ start_server {tags {"scan network"}} {

assert_equal 1000 [llength $keys]

# make sure that expired key have been removed by scan command
assert_equal 1000 [scan [regexp -inline {keys\=([\d]*)} [r info keyspace]] keys=%d]
# TODO: uncomment in redis 8.0
# make sure that only the expired key in the type match will been removed by scan command
#assert_equal 1001 [scan [regexp -inline {keys\=([\d]*)} [r info keyspace]] keys=%d]
assert_equal 1001 [scan [regexp -inline {keys\=([\d]*)} [r info keyspace]] keys=%d]

r debug set-active-expire 1
} {OK} {needs:debug}
Expand Down

0 comments on commit abafd80

Please sign in to comment.