]> git.saurik.com Git - redis.git/blobdiff - src/networking.c
Initial support for key expire times with millisecond resolution. RDB version is...
[redis.git] / src / networking.c
index a24c00e6a8838c8d2597f5ca2fdf4b0615a5c1af..edd7891d379dfe99328c8ad5dc74992de9ac38fc 100644 (file)
@@ -767,6 +767,17 @@ int processMultibulkBuffer(redisClient *c) {
             }
 
             pos += newline-(c->querybuf+pos)+2;
+            if (ll >= REDIS_MBULK_BIG_ARG) {
+                /* If we are going to read a large object from network
+                 * try to make it likely that it will start at c->querybuf
+                 * boundary so that we can optimized object creation
+                 * avoiding a large copy of data. */
+                c->querybuf = sdsrange(c->querybuf,pos,-1);
+                pos = 0;
+                /* Hint the sds library about the amount of bytes this string is
+                 * going to contain. */
+                c->querybuf = sdsMakeRoomFor(c->querybuf,ll+2);
+            }
             c->bulklen = ll;
         }
 
@@ -779,7 +790,7 @@ int processMultibulkBuffer(redisClient *c) {
              * instead of creating a new object by *copying* the sds we
              * just use the current sds string. */
             if (pos == 0 &&
-                sdslen(c->querybuf) > 4096 &&
+                c->bulklen >= REDIS_MBULK_BIG_ARG &&
                 (signed) sdslen(c->querybuf) == c->bulklen+2)
             {
                 c->argv[c->argc++] = createObject(REDIS_STRING,c->querybuf);
@@ -850,14 +861,29 @@ void processInputBuffer(redisClient *c) {
 
 void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
     redisClient *c = (redisClient*) privdata;
-    int nread;
+    int nread, readlen;
     size_t qblen;
     REDIS_NOTUSED(el);
     REDIS_NOTUSED(mask);
 
+    readlen = REDIS_IOBUF_LEN;
+    /* If this is a multi bulk request, and we are processing a bulk reply
+     * that is large enough, try to maximize the probabilty that the query
+     * buffer contains excatly the SDS string representing the object, even
+     * at the risk of requring more read(2) calls. This way the function
+     * processMultiBulkBuffer() can avoid copying buffers to create the
+     * Redis Object representing the argument. */
+    if (c->reqtype == REDIS_REQ_MULTIBULK && c->multibulklen && c->bulklen != -1
+        && c->bulklen >= REDIS_MBULK_BIG_ARG)
+    {
+        int remaining = (unsigned)(c->bulklen+2)-sdslen(c->querybuf);
+
+        if (remaining < readlen) readlen = remaining;
+    }
+
     qblen = sdslen(c->querybuf);
-    c->querybuf = sdsMakeRoomFor(c->querybuf, REDIS_IOBUF_LEN);
-    nread = read(fd, c->querybuf+qblen, REDIS_IOBUF_LEN);
+    c->querybuf = sdsMakeRoomFor(c->querybuf, readlen);
+    nread = read(fd, c->querybuf+qblen, readlen);
     if (nread == -1) {
         if (errno == EAGAIN) {
             nread = 0;