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