From c28b42acd9b32c8888d7265adc528ded7a787919 Mon Sep 17 00:00:00 2001 From: antirez Date: Wed, 18 Nov 2009 20:32:03 +0100 Subject: [PATCH] more experiments with long replies, glue output buffer, and writev. --- benchmark.c | 4 ++++ redis.c | 37 +++++++++++++++++-------------------- test-redis.tcl | 4 ++++ 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/benchmark.c b/benchmark.c index a933eba9..6b4fb2ff 100644 --- a/benchmark.c +++ b/benchmark.c @@ -486,6 +486,7 @@ int main(int argc, char **argv) { } do { +#if 0 prepareForBenchmark(); c = createClient(); if (!c) exit(1); @@ -547,6 +548,7 @@ int main(int argc, char **argv) { aeMain(config.el); endBenchmark("PING"); +#endif prepareForBenchmark(); c = createClient(); if (!c) exit(1); @@ -556,6 +558,7 @@ int main(int argc, char **argv) { aeMain(config.el); endBenchmark("LPUSH (again, in order to bench LRANGE)"); +#if 0 prepareForBenchmark(); c = createClient(); if (!c) exit(1); @@ -582,6 +585,7 @@ int main(int argc, char **argv) { createMissingClients(c); aeMain(config.el); endBenchmark("LRANGE (first 450 elements)"); +#endif prepareForBenchmark(); c = createClient(); diff --git a/redis.c b/redis.c index 52143e56..daf2c9bc 100644 --- a/redis.c +++ b/redis.c @@ -1351,33 +1351,29 @@ static void freeClient(redisClient *c) { #define GLUEREPLY_UP_TO (1024) static void glueReplyBuffersIfNeeded(redisClient *c) { - int totlen = 0; + int copylen = 0; + char buf[GLUEREPLY_UP_TO]; listNode *ln; robj *o; listRewind(c->reply); while((ln = listYield(c->reply))) { - o = ln->value; - totlen += sdslen(o->ptr); - /* This optimization makes more sense if we don't have to copy - * too much data */ - if (totlen > GLUEREPLY_UP_TO) return; - } - if (totlen > 0) { - char buf[GLUEREPLY_UP_TO]; - int copylen = 0; + int objlen; - listRewind(c->reply); - while((ln = listYield(c->reply))) { - o = ln->value; - memcpy(buf+copylen,o->ptr,sdslen(o->ptr)); - copylen += sdslen(o->ptr); + o = ln->value; + objlen = sdslen(o->ptr); + if (copylen + objlen <= GLUEREPLY_UP_TO) { + memcpy(buf+copylen,o->ptr,objlen); + copylen += objlen; listDelNode(c->reply,ln); + } else { + if (copylen == 0) return; + break; } - /* Now the output buffer is empty, add the new single element */ - o = createObject(REDIS_STRING,sdsnewlen(buf,totlen)); - listAddNodeTail(c->reply,o); } + /* Now the output buffer is empty, add the new single element */ + o = createObject(REDIS_STRING,sdsnewlen(buf,copylen)); + listAddNodeHead(c->reply,o); } static void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) { @@ -1387,8 +1383,6 @@ static void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) REDIS_NOTUSED(el); REDIS_NOTUSED(mask); - if (server.glueoutputbuf && listLength(c->reply) > 1) - glueReplyBuffersIfNeeded(c); /* Use writev() if we have enough buffers to send */ #if 0 @@ -1401,6 +1395,9 @@ static void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) #endif while(listLength(c->reply)) { + if (server.glueoutputbuf && listLength(c->reply) > 1) + glueReplyBuffersIfNeeded(c); + o = listNodeValue(listFirst(c->reply)); objlen = sdslen(o->ptr); diff --git a/test-redis.tcl b/test-redis.tcl index 1ca5e21a..400b0db5 100644 --- a/test-redis.tcl +++ b/test-redis.tcl @@ -912,6 +912,10 @@ proc main {server port} { lappend aux [$r dbsize] } {0 0} + test {Perform a final SAVE to leave a clean DB on disk} { + $r save + } {OK} + puts "\n[expr $::passed+$::failed] tests, $::passed passed, $::failed failed" if {$::failed > 0} { puts "\n*** WARNING!!! $::failed FAILED TESTS ***\n"