From 6f4aed59637d947265aefd5fe5b35256c0a0b3d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20S=C3=B6derqvist?= Date: Mon, 25 Nov 2024 13:28:19 +0100 Subject: [PATCH] Optimize expire check in scan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Viktor Söderqvist --- src/db.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/db.c b/src/db.c index 64534eb35b..bec8e11cc2 100644 --- a/src/db.c +++ b/src/db.c @@ -912,6 +912,7 @@ void keysCommand(client *c) { typedef struct { list *keys; /* elements that collect from dict */ robj *o; /* o must be a hash/set/zset object, NULL means current db */ + serverDb *db; /* database currently being scanned */ long long type; /* the particular type when scan the db */ sds pattern; /* pattern string, NULL means no pattern */ long sampled; /* cumulative number of keys sampled */ @@ -954,6 +955,15 @@ void keysScanCallback(void *privdata, void *entry) { } } + /* Handle and skip expired key. */ + if (objectIsExpired(obj)) { + robj kobj; + initStaticStringObject(kobj, key); + if (expireIfNeeded(data->db, &kobj, obj, 0) != KEY_VALID) { + return; + } + } + /* Keep this key. */ list *keys = data->keys; listAddNodeTail(keys, key); @@ -1184,6 +1194,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { * only keys are returned. */ scanData data = { .keys = keys, + .db = c->db, .o = o, .type = type, .pattern = use_pattern ? pat : NULL, @@ -1252,25 +1263,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { serverPanic("Not handled encoding in SCAN."); } - /* Step 3: Filter the expired keys */ - /* TODO: Do this in the keysScanCallback where we have the valkey objects - * that contain the TTL (or add valkey object to the list instead of just - * the keys). Then we don't need to look them up again here. */ - if (o == NULL && listLength(keys)) { - robj kobj; - listIter li; - listNode *ln; - listRewind(keys, &li); - while ((ln = listNext(&li))) { - sds key = listNodeValue(ln); - initStaticStringObject(kobj, key); - if (expireIfNeeded(c->db, &kobj, NULL, 0) != KEY_VALID) { - listDelNode(keys, ln); - } - } - } - - /* Step 4: Reply to the client. */ + /* Step 3: Reply to the client. */ addReplyArrayLen(c, 2); addReplyBulkLongLong(c, cursor);