On Thu, 12 Jun 2003, Justin Erenkrantz wrote:
> for (bucket = APR_BUCKET_FIRST(ctx->b);
> bucket != e && bucket != APR_BRIGADE_LAST(ctx->b);
> bucket = APR_BUCKET_NEXT(bucket)) {
> apr_bucket_remove(bucket);
> APR_BRIGADE_INSERT_TAIL(b, bucket);
> }
No! Bad!! The whole beauty of the ring data structure is that all of
these operations can be done in constant time, no loops. Bear with me,
and I'll explain.
> If you understand the type safety checks it is attempting, you are a far
> more intelligent person than I. =)
Well, I dunno about that... I do understand them but then again I've
focused on them since literally the day I started contributing to this lil
ole web server.
The following code assumes that ctx->b has at least one bucket in it,
namely e.
if (APR_BRIGADE_FIRST(ctx->b) != e)
{
/* move the sequence into the new brigade */
APR_RING_SPLICE_TAIL(&b->list,
APR_BRIGADE_FIRST(ctx->b),
APR_BUCKET_PREV(e),
apr_bucket, link);
/* fixup the dangling pointers in ctx->b */
APR_BRIGADE_FIRST(ctx->b) = e;
APR_BUCKET_PREV(e) = APR_BRIGADE_SENTINEL(ctx->b);
}
Lovely, eh? I didn't actually test this to make sure it's 100% right, but
conceptually I believe it should do the trick.
--Cliff