提交 442246dd 编写于 作者: A antirez

Precision of getClientOutputBufferMemoryUsage() greatily improved, see issue...

Precision of getClientOutputBufferMemoryUsage() greatily improved, see issue #327 for more information.
上级 8b7c3455
...@@ -151,7 +151,7 @@ void _addReplyObjectToList(redisClient *c, robj *o) { ...@@ -151,7 +151,7 @@ void _addReplyObjectToList(redisClient *c, robj *o) {
listAddNodeTail(c->reply,o); listAddNodeTail(c->reply,o);
} }
} }
c->reply_bytes += sdslen(o->ptr); c->reply_bytes += zmalloc_size(o->ptr);
asyncCloseClientOnOutputBufferLimitReached(c); asyncCloseClientOnOutputBufferLimitReached(c);
} }
...@@ -165,7 +165,7 @@ void _addReplySdsToList(redisClient *c, sds s) { ...@@ -165,7 +165,7 @@ void _addReplySdsToList(redisClient *c, sds s) {
return; return;
} }
c->reply_bytes += sdslen(s); c->reply_bytes += zmalloc_size(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 {
...@@ -191,7 +191,10 @@ void _addReplyStringToList(redisClient *c, char *s, size_t len) { ...@@ -191,7 +191,10 @@ void _addReplyStringToList(redisClient *c, char *s, size_t len) {
if (c->flags & REDIS_CLOSE_AFTER_REPLY) return; if (c->flags & REDIS_CLOSE_AFTER_REPLY) return;
if (listLength(c->reply) == 0) { if (listLength(c->reply) == 0) {
listAddNodeTail(c->reply,createStringObject(s,len)); robj *o = createStringObject(s,len);
listAddNodeTail(c->reply,o);
c->reply_bytes += zmalloc_size(o->ptr);
} else { } else {
tail = listNodeValue(listLast(c->reply)); tail = listNodeValue(listLast(c->reply));
...@@ -199,13 +202,17 @@ void _addReplyStringToList(redisClient *c, char *s, size_t len) { ...@@ -199,13 +202,17 @@ void _addReplyStringToList(redisClient *c, char *s, size_t len) {
if (tail->ptr != NULL && if (tail->ptr != NULL &&
sdslen(tail->ptr)+len <= REDIS_REPLY_CHUNK_BYTES) sdslen(tail->ptr)+len <= REDIS_REPLY_CHUNK_BYTES)
{ {
c->reply_bytes -= zmalloc_size(tail->ptr);
tail = dupLastObjectIfNeeded(c->reply); tail = dupLastObjectIfNeeded(c->reply);
tail->ptr = sdscatlen(tail->ptr,s,len); tail->ptr = sdscatlen(tail->ptr,s,len);
c->reply_bytes += zmalloc_size(tail->ptr);
} else { } else {
listAddNodeTail(c->reply,createStringObject(s,len)); robj *o = createStringObject(s,len);
listAddNodeTail(c->reply,o);
c->reply_bytes += zmalloc_size(o->ptr);
} }
} }
c->reply_bytes += len;
asyncCloseClientOnOutputBufferLimitReached(c); asyncCloseClientOnOutputBufferLimitReached(c);
} }
...@@ -336,7 +343,7 @@ void setDeferredMultiBulkLength(redisClient *c, void *node, long length) { ...@@ -336,7 +343,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); c->reply_bytes += zmalloc_size(len->ptr);
if (ln->next != NULL) { if (ln->next != NULL) {
next = listNodeValue(ln->next); next = listNodeValue(ln->next);
...@@ -638,6 +645,7 @@ void freeClientsInAsyncFreeQueue(void) { ...@@ -638,6 +645,7 @@ void freeClientsInAsyncFreeQueue(void) {
void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) { void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) {
redisClient *c = privdata; redisClient *c = privdata;
int nwritten = 0, totwritten = 0, objlen; int nwritten = 0, totwritten = 0, objlen;
size_t objmem;
robj *o; robj *o;
REDIS_NOTUSED(el); REDIS_NOTUSED(el);
REDIS_NOTUSED(mask); REDIS_NOTUSED(mask);
...@@ -663,6 +671,7 @@ void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) { ...@@ -663,6 +671,7 @@ void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) {
} else { } else {
o = listNodeValue(listFirst(c->reply)); o = listNodeValue(listFirst(c->reply));
objlen = sdslen(o->ptr); objlen = sdslen(o->ptr);
objmem = zmalloc_size(o->ptr);
if (objlen == 0) { if (objlen == 0) {
listDelNode(c->reply,listFirst(c->reply)); listDelNode(c->reply,listFirst(c->reply));
...@@ -683,7 +692,7 @@ void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) { ...@@ -683,7 +692,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; c->reply_bytes -= objmem;
} }
} }
/* Note that we avoid to send more than REDIS_MAX_WRITE_PER_EVENT /* Note that we avoid to send more than REDIS_MAX_WRITE_PER_EVENT
...@@ -1222,7 +1231,7 @@ void rewriteClientCommandArgument(redisClient *c, int i, robj *newval) { ...@@ -1222,7 +1231,7 @@ void rewriteClientCommandArgument(redisClient *c, int i, robj *newval) {
* the caller wishes. The main usage of this function currently is * the caller wishes. The main usage of this function currently is
* enforcing the client output length limits. */ * enforcing the client output length limits. */
unsigned long getClientOutputBufferMemoryUsage(redisClient *c) { unsigned long getClientOutputBufferMemoryUsage(redisClient *c) {
unsigned long list_item_size = sizeof(listNode); unsigned long list_item_size = sizeof(listNode)+sizeof(robj);
return c->reply_bytes + (list_item_size*listLength(c->reply)); return c->reply_bytes + (list_item_size*listLength(c->reply));
} }
......
...@@ -150,6 +150,20 @@ void *zrealloc(void *ptr, size_t size) { ...@@ -150,6 +150,20 @@ void *zrealloc(void *ptr, size_t size) {
#endif #endif
} }
/* Provide zmalloc_size() for systems where this function is not provided by
* malloc itself, given that in that case we store an header with this
* information as the first bytes of every allocation. */
#ifndef HAVE_MALLOC_SIZE
size_t zmalloc_size(void *ptr) {
void *realptr = (char*)ptr-PREFIX_SIZE;
size_t size = *((size_t*)realptr);
/* Assume at least that all the allocations are padded at sizeof(long) by
* the underlying allocator. */
if (size&(sizeof(long)-1)) size += sizeof(long)-(size&(sizeof(long)-1));
return size+PREFIX_SIZE;
}
#endif
void zfree(void *ptr) { void zfree(void *ptr) {
#ifndef HAVE_MALLOC_SIZE #ifndef HAVE_MALLOC_SIZE
void *realptr; void *realptr;
......
...@@ -76,4 +76,8 @@ void zmalloc_enable_thread_safeness(void); ...@@ -76,4 +76,8 @@ void zmalloc_enable_thread_safeness(void);
float zmalloc_get_fragmentation_ratio(void); float zmalloc_get_fragmentation_ratio(void);
size_t zmalloc_get_rss(void); size_t zmalloc_get_rss(void);
#ifndef HAVE_MALLOC_SIZE
size_t zmalloc_size(void *ptr);
#endif
#endif /* __ZMALLOC_H */ #endif /* __ZMALLOC_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册