gulaftab / redis

Automatically exported from code.google.com/p/redis
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

speed enhancement to keys * #311

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
This is a diff against 1.2.1.  The problem I encountered is that keys * isn't 
optimized and is a very common thing in our environment.  This change sped up 
the unit tests by 1.5-2.5s, and gave us much more notable benefits in 
production.  The change involved moving the if (pattern[0] == '*' && pattern[1] 
== '\0') outside of the while loop, so it is not evaluated for each key or 
before the other kind of glob pattern matching.

diff --git a/redis.c b/redis.c
index d2491a1..abd165a 100644
--- a/redis.c
+++ b/redis.c
@@ -3243,12 +3243,17 @@ static void keysCommand(redisClient *c) {
     di = dictGetIterator(c->db->dict);
     addReply(c,lenobj);
     decrRefCount(lenobj);
-    while((de = dictNext(di)) != NULL) {
-        robj *keyobj = dictGetEntryKey(de);

-        sds key = keyobj->ptr;
-        if ((pattern[0] == '*' && pattern[1] == '\0') ||
-            stringmatchlen(pattern,plen,key,sdslen(key),0)) {
+    //
+    // match on the general common case before while loop to prevent
+    // this conditional from being run for each key
+    // and/or before any other glob pattern match attempt
+    //
+    if (pattern[0] == '*' && pattern[1] == '\0') {
+        while((de = dictNext(di)) != NULL) {
+            robj *keyobj = dictGetEntryKey(de);
+    
+            sds key = keyobj->ptr;
             if (expireIfNeeded(c->db,keyobj) == 0) {
                 if (numkeys != 0)
                     addReply(c,shared.space);
@@ -3258,6 +3263,22 @@ static void keysCommand(redisClient *c) {
             }
         }
     }
+    else {
+        while((de = dictNext(di)) != NULL) {
+            robj *keyobj = dictGetEntryKey(de);
+    
+            sds key = keyobj->ptr;
+            if (stringmatchlen(pattern,plen,key,sdslen(key),0)) {
+                if (expireIfNeeded(c->db,keyobj) == 0) {
+                    if (numkeys != 0)
+                        addReply(c,shared.space);
+                    addReply(c,keyobj);
+                    numkeys++;
+                    keyslen += sdslen(key);
+                }
+            }
+        }
+    }
     dictReleaseIterator(di);
     lenobj->ptr = sdscatprintf(sdsempty(),"$%lu\r\n",keyslen+(numkeys ? (numkeys-1) : 0));
     addReply(c,shared.crlf);

Original issue reported on code.google.com by dsrtho...@gmail.com on 23 Aug 2010 at 8:40

GoogleCodeExporter commented 9 years ago
Unfortunately I don't see a way for me to set the type on this issue to 
enhancement instead of defect, so I can't categorize it appropriately.

Original comment by dsrtho...@gmail.com on 23 Aug 2010 at 8:41

GoogleCodeExporter commented 9 years ago
I can't reproduce the speedup... please can you provide some information about 
the dataset size, the actual testing methodology and alike? Thanks!

Original comment by anti...@gmail.com on 30 Aug 2010 at 9:46

GoogleCodeExporter commented 9 years ago

Original comment by anti...@gmail.com on 30 Aug 2010 at 1:45