Commit 05755f5c authored by antirez's avatar antirez
Browse files

Initial version of c->reply_bytes implementation backported from unstable to...

Initial version of c->reply_bytes implementation backported from unstable to 2.4, in order to apply issue 327 patches.
parent 02b984c2
...@@ -261,6 +261,7 @@ struct redisClient *createFakeClient(void) { ...@@ -261,6 +261,7 @@ struct redisClient *createFakeClient(void) {
* so that Redis will not try to send replies to this client. */ * so that Redis will not try to send replies to this client. */
c->replstate = REDIS_REPL_WAIT_BGSAVE_START; c->replstate = REDIS_REPL_WAIT_BGSAVE_START;
c->reply = listCreate(); c->reply = listCreate();
c->reply_bytes = 0;
c->watched_keys = listCreate(); c->watched_keys = listCreate();
listSetFreeMethod(c->reply,decrRefCount); listSetFreeMethod(c->reply,decrRefCount);
listSetDupMethod(c->reply,dupClientReplyValue); listSetDupMethod(c->reply,dupClientReplyValue);
......
...@@ -41,6 +41,7 @@ redisClient *createClient(int fd) { ...@@ -41,6 +41,7 @@ redisClient *createClient(int fd) {
c->authenticated = 0; c->authenticated = 0;
c->replstate = REDIS_REPL_NONE; c->replstate = REDIS_REPL_NONE;
c->reply = listCreate(); c->reply = listCreate();
c->reply_bytes = 0;
listSetFreeMethod(c->reply,decrRefCount); listSetFreeMethod(c->reply,decrRefCount);
listSetDupMethod(c->reply,dupClientReplyValue); listSetDupMethod(c->reply,dupClientReplyValue);
c->bpop.keys = NULL; c->bpop.keys = NULL;
...@@ -130,6 +131,7 @@ void _addReplyObjectToList(redisClient *c, robj *o) { ...@@ -130,6 +131,7 @@ void _addReplyObjectToList(redisClient *c, robj *o) {
listAddNodeTail(c->reply,o); listAddNodeTail(c->reply,o);
} }
} }
c->reply_bytes += sdslen(o->ptr);
} }
/* This method takes responsibility over the sds. When it is no longer /* This method takes responsibility over the sds. When it is no longer
...@@ -142,6 +144,7 @@ void _addReplySdsToList(redisClient *c, sds s) { ...@@ -142,6 +144,7 @@ void _addReplySdsToList(redisClient *c, sds s) {
return; return;
} }
c->reply_bytes += sdslen(s);
if (listLength(c->reply) == 0) { if (listLength(c->reply) == 0) {
listAddNodeTail(c->reply,createObject(REDIS_STRING,s)); listAddNodeTail(c->reply,createObject(REDIS_STRING,s));
} else { } else {
...@@ -180,6 +183,7 @@ void _addReplyStringToList(redisClient *c, char *s, size_t len) { ...@@ -180,6 +183,7 @@ void _addReplyStringToList(redisClient *c, char *s, size_t len) {
listAddNodeTail(c->reply,createStringObject(s,len)); listAddNodeTail(c->reply,createStringObject(s,len));
} }
} }
c->reply_bytes += len;
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
...@@ -291,6 +295,7 @@ void setDeferredMultiBulkLength(redisClient *c, void *node, long length) { ...@@ -291,6 +295,7 @@ void setDeferredMultiBulkLength(redisClient *c, void *node, long length) {
len = listNodeValue(ln); len = listNodeValue(ln);
len->ptr = sdscatprintf(sdsempty(),"*%ld\r\n",length); len->ptr = sdscatprintf(sdsempty(),"*%ld\r\n",length);
c->reply_bytes += sdslen(len->ptr);
if (ln->next != NULL) { if (ln->next != NULL) {
next = listNodeValue(ln->next); next = listNodeValue(ln->next);
...@@ -398,6 +403,7 @@ void copyClientOutputBuffer(redisClient *dst, redisClient *src) { ...@@ -398,6 +403,7 @@ void copyClientOutputBuffer(redisClient *dst, redisClient *src) {
dst->reply = listDup(src->reply); dst->reply = listDup(src->reply);
memcpy(dst->buf,src->buf,src->bufpos); memcpy(dst->buf,src->buf,src->bufpos);
dst->bufpos = src->bufpos; dst->bufpos = src->bufpos;
dst->reply_bytes = src->reply_bytes;
} }
static void acceptCommonHandler(int fd) { static void acceptCommonHandler(int fd) {
...@@ -611,6 +617,7 @@ void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) { ...@@ -611,6 +617,7 @@ void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) {
if (c->sentlen == objlen) { if (c->sentlen == objlen) {
listDelNode(c->reply,listFirst(c->reply)); listDelNode(c->reply,listFirst(c->reply));
c->sentlen = 0; c->sentlen = 0;
c->reply_bytes -= objlen;
} }
} }
/* Note that we avoid to send more thank REDIS_MAX_WRITE_PER_EVENT /* Note that we avoid to send more thank REDIS_MAX_WRITE_PER_EVENT
...@@ -1060,3 +1067,22 @@ void rewriteClientCommandVector(redisClient *c, int argc, ...) { ...@@ -1060,3 +1067,22 @@ void rewriteClientCommandVector(redisClient *c, int argc, ...) {
redisAssert(c->cmd != NULL); redisAssert(c->cmd != NULL);
va_end(ap); va_end(ap);
} }
/* This function returns the number of bytes that Redis is virtually
* using to store the reply still not read by the client.
* It is "virtual" since the reply output list may contain objects that
* are shared and are not really using additional memory.
*
* The function returns the total sum of the length of all the objects
* stored in the output list, plus the memory used to allocate every
* list node. The static reply buffer is not taken into account since it
* is allocated anyway.
*
* Note: this function is very fast so can be called as many time as
* the caller wishes. The main usage of this function currently is
* enforcing the client output length limits. */
unsigned long getClientOutputBufferMemoryUsage(redisClient *c) {
unsigned long list_item_size = sizeof(listNode);
return c->reply_bytes + (list_item_size*listLength(c->reply));
}
...@@ -339,6 +339,7 @@ typedef struct redisClient { ...@@ -339,6 +339,7 @@ typedef struct redisClient {
int multibulklen; /* number of multi bulk arguments left to read */ int multibulklen; /* number of multi bulk arguments left to read */
long bulklen; /* length of bulk argument in multi bulk request */ long bulklen; /* length of bulk argument in multi bulk request */
list *reply; list *reply;
unsigned long reply_bytes; /* Tot bytes of objects in reply list */
int sentlen; int sentlen;
time_t lastinteraction; /* time of the last interaction, used for timeout */ time_t lastinteraction; /* time of the last interaction, used for timeout */
int flags; /* REDIS_SLAVE | REDIS_MONITOR | REDIS_MULTI ... */ int flags; /* REDIS_SLAVE | REDIS_MONITOR | REDIS_MULTI ... */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment