From ec7f480e11e1b697c05ac40d69a6a9fca88fc439 Mon Sep 17 00:00:00 2001 From: antirez Date: Tue, 23 Jul 2013 11:50:17 +0200 Subject: [PATCH] getStringObjectSdsUsedMemory() function added. Now that EMBSTR encoding exists we calculate the amount of memory used by the SDS part of a Redis String object in two different ways: 1) For raw string object, the size of the allocation is considered. 2) For embstr objects, the length of the string itself is used. The new function takes care of this logic. --- src/networking.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/networking.c b/src/networking.c index 847e80c1..54dfc025 100644 --- a/src/networking.c +++ b/src/networking.c @@ -41,6 +41,17 @@ size_t zmalloc_size_sds(sds s) { return zmalloc_size(s-sizeof(struct sdshdr)); } +/* Return the amount of memory used by the sds string at object->ptr + * for a string object. */ +size_t getStringObjectSdsUsedMemory(robj *o) { + redisAssertWithInfo(NULL,o,o->type == REDIS_STRING); + switch(o->encoding) { + case REDIS_ENCODING_RAW: return zmalloc_size_sds(o->ptr); + case REDIS_ENCODING_EMBSTR: return sdslen(o->ptr); + default: return 0; /* Just integer encoding for now. */ + } +} + void *dupClientReplyValue(void *o) { incrRefCount((robj*)o); return o; @@ -184,9 +195,7 @@ void _addReplyObjectToList(redisClient *c, robj *o) { if (listLength(c->reply) == 0) { incrRefCount(o); listAddNodeTail(c->reply,o); - c->reply_bytes += (o->encoding == REDIS_ENCODING_RAW) ? - zmalloc_size_sds(o->ptr) : - sdslen(o->ptr); + c->reply_bytes += getStringObjectSdsUsedMemory(o); } else { tail = listNodeValue(listLast(c->reply)); @@ -202,9 +211,7 @@ void _addReplyObjectToList(redisClient *c, robj *o) { } else { incrRefCount(o); listAddNodeTail(c->reply,o); - c->reply_bytes += (o->encoding == REDIS_ENCODING_RAW) ? - zmalloc_size_sds(o->ptr) : - sdslen(o->ptr); + c->reply_bytes += getStringObjectSdsUsedMemory(o); } } asyncCloseClientOnOutputBufferLimitReached(c); @@ -252,9 +259,7 @@ void _addReplyStringToList(redisClient *c, char *s, size_t len) { robj *o = createStringObject(s,len); listAddNodeTail(c->reply,o); - c->reply_bytes += (o->encoding == REDIS_ENCODING_RAW) ? - zmalloc_size_sds(o->ptr) : - sdslen(o->ptr); + c->reply_bytes += getStringObjectSdsUsedMemory(o); } else { tail = listNodeValue(listLast(c->reply)); @@ -270,9 +275,7 @@ void _addReplyStringToList(redisClient *c, char *s, size_t len) { robj *o = createStringObject(s,len); listAddNodeTail(c->reply,o); - c->reply_bytes += (o->encoding == REDIS_ENCODING_RAW) ? - zmalloc_size_sds(o->ptr) : - sdslen(o->ptr); + c->reply_bytes += getStringObjectSdsUsedMemory(o); } } asyncCloseClientOnOutputBufferLimitReached(c); @@ -413,10 +416,7 @@ void setDeferredMultiBulkLength(redisClient *c, void *node, long length) { /* Only glue when the next node is non-NULL (an sds in this case) */ if (next->ptr != NULL) { c->reply_bytes -= zmalloc_size_sds(len->ptr); - if (next->encoding == REDIS_ENCODING_RAW) - c->reply_bytes -= zmalloc_size_sds(next->ptr); - else - c->reply_bytes -= sdslen(next->ptr); + c->reply_bytes -= getStringObjectSdsUsedMemory(next); len->ptr = sdscatlen(len->ptr,next->ptr,sdslen(next->ptr)); c->reply_bytes += zmalloc_size_sds(len->ptr); listDelNode(c->reply,ln->next); @@ -778,9 +778,7 @@ void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) { } else { o = listNodeValue(listFirst(c->reply)); objlen = sdslen(o->ptr); - objmem = (o->encoding == REDIS_ENCODING_RAW) ? - zmalloc_size_sds(o->ptr) : - sdslen(o->ptr); + objmem = getStringObjectSdsUsedMemory(o); if (objlen == 0) { listDelNode(c->reply,listFirst(c->reply));