store the hash iterator on the heap instead of the stack

This commit is contained in:
Pieter Noordhuis 2010-04-16 12:48:48 +02:00
parent c811bb381d
commit c44d3b56df

17
redis.c
View File

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