Robert Greig wrote:
On 19/09/2007, Rafael Schloming <[EMAIL PROTECTED]> wrote:

At a minimum it would be nice if FieldTable implemented the Map
interface and had a copy constructor that took a regular Map.

In fact FieldTable used to be a subclass of HashMap (or AbstractMap or
something like that). I cannot remember why that was changed now - Rob
can you recall?

This analysis gets a little more complicated in 0-10. In 0-10 a frame
boundary can appear anywhere, so it isn't possible to simply wrap the
bytes read in off the wire in an AMQShortString object and pass that up.

In a sense we have this today (if I understand you correctly) since
you may only read a partial frame off the wire. That is a lower level
obviously but is AFAICS exactly the same problem.

Yes, except 0-10 adds another level of this since frames are the unit you read off of the wire, and those can't be directly parsed without aggregating them. So for the 0-10 transport code you either end up doing two full copies if you want to provide contiguous byte buffers to the codec, or you make the codec deal with non contiguous byte buffers. I chose the latter, and also stopped using the CumulativeProtocolDecoder as there was no need anymore.

I have discussed in the past using a special implementation of
ByteBuffer that can aggregate sub byte buffers to avoid copying (that
is currently done in the CumulativeProtocolDecoder or something like
that).

I have something similar to this. It's not an implementation of ByteBuffer, it's just a Decoder object that knows how to read primitive AMQP types out of a list of multiple ByteBuffers. It's a bit simpler than a full ByteBuffer impl, but it has much the same effect.

You either need to copy the bytes into a newly allocated ByteBuffer, or
have a more sophisticated AMQShortString implementation that operates on
a list of fragments. Obviously it is impossible to do the latter if
AMQShortString is used directly throughout the code.

I don't follow the last sentence? AMQShortString would contain a
subclass of ByteBuffer that under the hood was really multiple
java.nio.ByteBuffer slices.

You're right, in theory I could modify or subclass the MINA ByteBuffer to provide this functionality. That is something I would rather avoid doing though as to date I've managed to keep MINA dependencies quite isolated.

I actually do want to expose a non JMS interface that doesn't use
AMQShortString. There is a lot of ground between providing an AMQP
specific messaging API and providing an AMQP specific String API.

And you want to postpone the creation of an AMQShortString? Your API
layer could presumably hide that from the user of your API in the same
way JMS does?

I actually don't want to bother going through AMQShortString at all. If the user passes me a String the most efficient thing for me to do is encode that directly onto the wire.

Why does postponing the creation of the AMQShortString help? Are there
cases where you might choose not to encode the string into a
bytebuffer? Or are you avoiding the case of copying into a bytebuffer
then copying that buffer into the buffer that contains the whole
frame?

Yes, I'm avoiding that extra copy.

The other issue is that the generated API is at this point quite usable on its own, however usage of AMQShortString would make it unsuitable as a public API. So I'm forced to make something of a choice here, either generate code that is unusable as a public API, or generate code that is unusable by the broker because it is too slow.

That's why I'm trying to figure out if there are any options that satisfy both constraints, e.g. using CharSequence. It would make the generated code a whole lot more usable as a public API since on the input side you could just pass in a String directly without wrapping it, and it would permit the same optimized decoding that AMQShortString does. Obviously on the output side if you actually needed a concrete String you would still need to call toString(), but many of the java APIs will let you pass in a CharSequence anyways.

--Rafael

Reply via email to