diff options
author | Graham Leggett <minfrin@apache.org> | 2008-11-16 22:23:25 +0000 |
---|---|---|
committer | Graham Leggett <minfrin@apache.org> | 2008-11-16 22:23:25 +0000 |
commit | 5b28da886ca24fb6bd4ff6f3ae6edd4d5978924d (patch) | |
tree | 90cb7144454e25cdeb3de361384832f45add0719 /modules | |
parent | 49ec47f7218d4a5a37a4d8af79b28d3b22688f4e (diff) | |
download | httpd-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.c | 26 |
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; |