]> git.saurik.com Git - redis.git/commitdiff
Use safe dictionary iterator from KEYS
authorPieter Noordhuis <pcnoordhuis@gmail.com>
Mon, 30 Apr 2012 17:16:20 +0000 (10:16 -0700)
committerantirez <antirez@gmail.com>
Tue, 1 May 2012 08:52:03 +0000 (10:52 +0200)
Every matched key in a KEYS call is checked for expiration. When the key
is set to expire, the call to `getExpire` will assert that the key also
exists in the main dictionary. This in turn causes a rehashing step to
be executed. Rehashing a dictionary when there is an iterator active may
result in the iterator emitting duplicate entries, or not emitting some
entries at all. By using a safe iterator, the rehash step is omitted.

src/db.c

index fff63f4846f86c88b0cc00db449931f71de97e7a..6447838caa7e19f98378eeeed940c64de222001d 100644 (file)
--- a/src/db.c
+++ b/src/db.c
@@ -261,7 +261,7 @@ void keysCommand(redisClient *c) {
     unsigned long numkeys = 0;
     void *replylen = addDeferredMultiBulkLength(c);
 
     unsigned long numkeys = 0;
     void *replylen = addDeferredMultiBulkLength(c);
 
-    di = dictGetIterator(c->db->dict);
+    di = dictGetSafeIterator(c->db->dict);
     allkeys = (pattern[0] == '*' && pattern[1] == '\0');
     while((de = dictNext(di)) != NULL) {
         sds key = dictGetKey(de);
     allkeys = (pattern[0] == '*' && pattern[1] == '\0');
     while((de = dictNext(di)) != NULL) {
         sds key = dictGetKey(de);