summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorGraham Leggett <minfrin@apache.org>2008-11-16 22:23:25 +0000
committerGraham Leggett <minfrin@apache.org>2008-11-16 22:23:25 +0000
commit5b28da886ca24fb6bd4ff6f3ae6edd4d5978924d (patch)
tree90cb7144454e25cdeb3de361384832f45add0719 /modules
parent49ec47f7218d4a5a37a4d8af79b28d3b22688f4e (diff)
downloadhttpd-5b28da886ca24fb6bd4ff6f3ae6edd4d5978924d.tar.gz
mod_buffer: Optimise the buffering of heap buckets when the heap
buckets stay exactly APR_BUCKET_BUFF_SIZE long. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@718125 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r--modules/filters/mod_buffer.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/modules/filters/mod_buffer.c b/modules/filters/mod_buffer.c
index c8e3bf38e2..08a800f3e2 100644
--- a/modules/filters/mod_buffer.c
+++ b/modules/filters/mod_buffer.c
@@ -57,6 +57,7 @@ static apr_status_t buffer_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) {
request_rec *r = f->r;
buffer_ctx *ctx = f->ctx;
apr_status_t rv = APR_SUCCESS;
+ int move = 0;
/* first time in? create a context */
if (!ctx) {
@@ -81,6 +82,11 @@ static apr_status_t buffer_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) {
return ap_pass_brigade(f->next, bb);
}
+ /* Empty buffer means we can potentially optimise below */
+ if (APR_BRIGADE_EMPTY(ctx->bb)) {
+ move = 1;
+ }
+
while (APR_SUCCESS == rv && !APR_BRIGADE_EMPTY(bb)) {
const char *data;
apr_off_t len;
@@ -146,10 +152,26 @@ static apr_status_t buffer_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) {
*/
if (APR_SUCCESS == (rv = apr_bucket_read(e, &data, &size,
APR_BLOCK_READ))) {
- apr_brigade_write(ctx->bb, NULL, NULL, data, size);
+
+ /* further optimisation: if the buckets are already heap
+ * buckets, and the buckets stay exactly APR_BUCKET_BUFF_SIZE
+ * long (as they would be if we were reading bits of a
+ * large bucket), then move the buckets instead of copying
+ * them.
+ */
+ if (move && APR_BUCKET_IS_HEAP(e)) {
+ APR_BUCKET_REMOVE(e);
+ APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
+ if (APR_BUCKET_BUFF_SIZE != size) {
+ move = 0;
+ }
+ } else {
+ apr_brigade_write(ctx->bb, NULL, NULL, data, size);
+ apr_bucket_delete(e);
+ }
+
}
- apr_bucket_delete(e);
}
return rv;