]> git.saurik.com Git - redis.git/commitdiff
store the hash iterator on the heap instead of the stack
authorPieter Noordhuis <pcnoordhuis@gmail.com>
Fri, 16 Apr 2010 10:48:48 +0000 (12:48 +0200)
committerPieter Noordhuis <pcnoordhuis@gmail.com>
Fri, 16 Apr 2010 10:48:48 +0000 (12:48 +0200)
redis.c

diff --git a/redis.c b/redis.c
index 5227ca9610e48bab5c3390d1ba4ee8ddee008b8e..4627c681cccd9737f41afea182430050873bf8f2 100644 (file)
--- a/redis.c
+++ b/redis.c
@@ -6174,7 +6174,8 @@ typedef struct {
     dictEntry *de;
 } hashIterator;
 
-static void hashInitIterator(robj *subject, hashIterator *hi) {
+static hashIterator *hashInitIterator(robj *subject) {
+    hashIterator *hi = zmalloc(sizeof(hashIterator));
     hi->encoding = subject->encoding;
     if (hi->encoding == REDIS_ENCODING_ZIPMAP) {
         hi->zi = zipmapRewind(subject->ptr);
@@ -6183,12 +6184,14 @@ static void hashInitIterator(robj *subject, hashIterator *hi) {
     } else {
         redisAssert(NULL);
     }
+    return hi;
 }
 
 static void hashReleaseIterator(hashIterator *hi) {
     if (hi->encoding == REDIS_ENCODING_HT) {
         dictReleaseIterator(hi->di);
     }
+    zfree(hi);
 }
 
 /* Move to the next entry in the hash. Return REDIS_OK when the next entry
@@ -6372,7 +6375,7 @@ static void hlenCommand(redisClient *c) {
 static void genericHgetallCommand(redisClient *c, int flags) {
     robj *o, *lenobj, *obj;
     unsigned long count = 0;
-    hashIterator hi;
+    hashIterator *hi;
 
     if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptymultibulk)) == NULL
         || checkType(c,o,REDIS_HASH)) return;
@@ -6381,20 +6384,20 @@ static void genericHgetallCommand(redisClient *c, int flags) {
     addReply(c,lenobj);
     decrRefCount(lenobj);
 
-    hashInitIterator(o, &hi);
-    while (hashNext(&hi) != REDIS_ERR) {
+    hi = hashInitIterator(o);
+    while (hashNext(hi) != REDIS_ERR) {
         if (flags & REDIS_HASH_KEY) {
-            obj = hashCurrent(&hi,REDIS_HASH_KEY);
+            obj = hashCurrent(hi,REDIS_HASH_KEY);
             addReplyBulk(c,obj);
             count++;
         }
         if (flags & REDIS_HASH_VALUE) {
-            obj = hashCurrent(&hi,REDIS_HASH_VALUE);
+            obj = hashCurrent(hi,REDIS_HASH_VALUE);
             addReplyBulk(c,obj);
             count++;
         }
     }
-    hashReleaseIterator(&hi);
+    hashReleaseIterator(hi);
 
     lenobj->ptr = sdscatprintf(sdsempty(),"*%lu\r\n",count);
 }