apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Greg Stein <gst...@lyra.org>
Subject Re: cvs commit: apr-util CHANGES
Date Sun, 22 Sep 2002 23:34:59 GMT
On Sat, Sep 21, 2002 at 11:40:41PM -0000, brianp@apache.org wrote:
>...
>   +{
>   +    apr_bucket *e = APR_BRIGADE_LAST(b);
>   +    apr_size_t remaining;
>   +    char *buf;
>   +    apr_size_t bytes_written = 0;
>   +    apr_size_t i;
>   +
>   +    /* Step 1: check if there is a heap bucket at the end
>   +     * of the brigade already
>   +     */
>   +    if (!APR_BRIGADE_EMPTY(b) && APR_BUCKET_IS_HEAP(e)) {
>   +        apr_bucket_heap *h = e->data;
>   +        remaining = h->alloc_len - (e->length + (apr_size_t)e->start);
>   +        buf = h->base + e->start + e->length;
>   +    }
>   +    else {
>   +        remaining = 0;
>   +        buf = NULL;
>   +    }
>   +
>   +    /* Step 2: copy the data into the heap bucket, appending
>   +     * a new heap bucket each time the old one becomes full
>   +     */
>   +    for (i = 0; i < nvec; i++) {
>   +        apr_size_t nbyte = vec[i].iov_len;
>   +        const char *str = (const char *)(vec[i].iov_base);
>   +
>   +        bytes_written += nbyte;
>   +        if (nbyte <= remaining) {
>   +            memcpy(buf, str, nbyte);
>   +            e->length += nbyte;
>   +            buf += nbyte;
>   +            remaining -= nbyte;
>   +        }
>   +        else if (nbyte < APR_BUCKET_BUFF_SIZE) {
>   +            buf = apr_bucket_alloc(APR_BUCKET_BUFF_SIZE, b->bucket_alloc);
>   +            e = apr_bucket_heap_create(buf, APR_BUCKET_BUFF_SIZE,
>   +                                       apr_bucket_free, b->bucket_alloc);
>   +            APR_BRIGADE_INSERT_TAIL(b, e);
>   +            memcpy(buf, str, nbyte);
>   +            e->length = nbyte;
>   +            buf += nbyte;
>   +            remaining = APR_BUCKET_BUFF_SIZE - nbyte;
>   +        }
>   +        else { /* String larger than APR_BUCKET_BUFF_SIZE */
>   +            e = apr_bucket_transient_create(str, nbyte, b->bucket_alloc);
>   +            APR_BRIGADE_INSERT_TAIL(b, e);
>   +            remaining = 0; /* create a new heap bucket for the next write */
>   +        }

Ewww... icky implementation... If you have a dozen iovec's where each
iov_len is slightly less than APR_BUCKET_BUFF_SIZE, then you're going to
copy the entire thing onto the heap.

>   +    /* Step 3: if necessary, output the brigade contents now
>   +     */
>   +    if (bytes_written >= APR_BUCKET_BUFF_SIZE) {
>   +        return flush(b, ctx);
>   +    }

And *then* you're going to flush the thing.

If you total up the number of bytes represented by the iovec, and that total
is more than APR_BUCKET_BUFF_SIZE, then simply create <nvec> TRANSIENT
buckets and flush the thing. No copies at all.

If the total is less, then go ahead and shove the iovec's onto the existing
HEAP bucket, and/or one or two new HEAP buckets (you can show that you'll
never need more than two (existing/created) buckets altogether).

I also think that doing it this way will also greatly simplify the code.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/

Mime
View raw message