serf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhuij...@apache.org
Subject svn commit: r1711984 - /serf/trunk/buckets/copy_buckets.c
Date Mon, 02 Nov 2015 13:46:40 GMT
Author: rhuijben
Date: Mon Nov  2 13:46:40 2015
New Revision: 1711984

URL: http://svn.apache.org/viewvc?rev=1711984&view=rev
Log:
Simplify some code in the copy bucket code and avoid copying data
(and allocating the buffer) in a not unlikely scenario.

* buckets/copy_buckets.c
  (serf__copy_iovec): New helper function.
  (serf_copy_read): Avoid allocating+copying when we only return
    the first result of the iovec read. Extract copy code.
  (serf_copy_read_iovec): Extract copy code to improve readability.

Modified:
    serf/trunk/buckets/copy_buckets.c

Modified: serf/trunk/buckets/copy_buckets.c
URL: http://svn.apache.org/viewvc/serf/trunk/buckets/copy_buckets.c?rev=1711984&r1=1711983&r2=1711984&view=diff
==============================================================================
--- serf/trunk/buckets/copy_buckets.c (original)
+++ serf/trunk/buckets/copy_buckets.c Mon Nov  2 13:46:40 2015
@@ -58,6 +58,24 @@ serf_bucket_t *serf_bucket_copy_create(
     return serf_bucket_create(&serf_bucket_type_copy, allocator, ctx);
 }
 
+static void serf__copy_iovec(char *data,
+                             apr_size_t *copied,
+                             struct iovec *vecs,
+                             int vecs_used)
+{
+    int i;
+    apr_size_t sz = 0;
+
+    for (i = 0; i < vecs_used; i++) {
+        memcpy(data, vecs[i].iov_base, vecs[i].iov_len);
+        data += vecs[i].iov_len;
+        sz += vecs[i].iov_len;
+    }
+
+    if (copied)
+      *copied = sz;
+}
+
 static apr_status_t serf_copy_read(serf_bucket_t *bucket,
                                    apr_size_t requested,
                                    const char **data, apr_size_t *len)
@@ -66,8 +84,6 @@ static apr_status_t serf_copy_read(serf_
     apr_status_t status;
     const char *wdata;
     apr_size_t peek_len;
-    struct iovec vecs[16];
-    int vecs_used;
     apr_size_t fetched;
 
     status = serf_bucket_peek(ctx->wrapped, &wdata, &peek_len);
@@ -83,17 +99,16 @@ static apr_status_t serf_copy_read(serf_
         return serf_bucket_read(ctx->wrapped, requested, data, len);
     }
 
-    if (! ctx->hold_buf)
-        ctx->hold_buf = serf_bucket_mem_alloc(bucket->allocator,
-                                              ctx->min_size);
-
-    /* Reduce requested to fit in our buffer if necessary*/
+    /* Reduce requested to fit in our buffer */
     if (requested > ctx->min_size)
         requested = ctx->min_size;
 
     fetched = 0;
     while (fetched < requested) {
-        int i;
+        struct iovec vecs[16];
+        int vecs_used;
+        apr_size_t read;
+
         status = serf_bucket_read_iovec(ctx->wrapped, requested - fetched,
                                         16, vecs, &vecs_used);
 
@@ -102,12 +117,31 @@ static apr_status_t serf_copy_read(serf_
                 status = APR_EAGAIN;
             break;
         }
+        else if (!fetched && vecs_used == 1
+                 && (status || (vecs[0].iov_len == requested))) {
+
+            /* Easy out
+                * We don't have anything stashed
+                * We only have one buffer to return
+                * And either
+                    - We can't read any further at this time
+                    - Or the buffer is already filled
+             */
+
+            *data = vecs[0].iov_base;
+            *len = vecs[0].iov_len;
+            return status;
+        }
+        else if (!ctx->hold_buf && vecs_used > 0) {
+            /* We have something that we want to store */
 
-        for (i = 0; i < vecs_used; i++) {
-            memcpy(ctx->hold_buf + fetched, vecs[i].iov_base, vecs[i].iov_len);
-            fetched += vecs[i].iov_len;
+            ctx->hold_buf = serf_bucket_mem_alloc(bucket->allocator,
+                                                  ctx->min_size);
         }
 
+        serf__copy_iovec(ctx->hold_buf + fetched, &read, vecs, vecs_used);
+        fetched += read;
+
         if (status)
             break;
     }
@@ -196,12 +230,8 @@ static apr_status_t serf_copy_read_iovec
                                               ctx->min_size);
 
     /* ### copy into HOLD_BUF. then read/append some more.  */
-    fetched = 0;
-    for (i = 0; i < *vecs_used; i++) {
-        memcpy(ctx->hold_buf + fetched, vecs[i].iov_base, vecs[i].iov_len);
-        fetched += vecs[i].iov_len;
-    }
-
+    fetched = total;
+    serf__copy_iovec(ctx->hold_buf, NULL, vecs, *vecs_used);
 
     /* ### point vecs[0] at HOLD_BUF.  */
     vecs[0].iov_base = ctx->hold_buf;
@@ -226,12 +256,9 @@ static apr_status_t serf_copy_read_iovec
             return status;
         }
 
-        for (i = 1; i <= v_used; i++) {
-            memcpy(ctx->hold_buf + fetched, vecs[i].iov_base,
-                    vecs[i].iov_len);
-            fetched += vecs[i].iov_len;
-        }
+        serf__copy_iovec(ctx->hold_buf + fetched, NULL, &vecs[1], v_used);
 
+        fetched += total;
         vecs[0].iov_len = fetched;
     }
 }



Mime
View raw message