Every Java circular byte buffer implementation I have seen referenced on SO and elsewhere does not extend java.nio.ByteBuffer, which for me is necessary for use with a SocketChannel. Does anyone know of an open source implementation that extends ByteBuffer. I tried going down the road of writing my own, but got stuck when I realized that the position and remaining functions are final and I was going to override those to adjust for head and prevent buffer overflow exceptions. In sending 5000 messages over a socket channel with every one needing me to copy stuff to the head of a linear buffer this adds about 450ms or 90us per message(which contains 10 packets, so 9us per packet). Right now the only method that I can think of that would work is to override every single method and rewrite everything. Any ideas?
4 Answers
Instead of creating a circular buffer you can make the buffer much larger than one message. Say the maximum message size is N bytes. Create a buffer which is 100 * N bytes are only compact() the ByteBuffer when there is less than N bytes left. This will reduce the amount of copying by a factor of 100.
Another optimisation is to compact() the ByteBuffer whenever there is no remaining data as this is very fast.
6 Comments
buffer().mark(). buffer.position(buffer.limit()).limit(buffer.capacity());. The mark is shows where the reading may start.; Also my guideline for the buffer.capacity is exactly the same as the socket.writebufferYou cannot extend java.nio.ByteBuffer, simple as that. The c-tor is package private. It will NOT work, b/c the main idea is passing the address to some C code. Also you cannot override anything since many of the methods are final. ByteBuffers have been engineered for speed and some of the decisions may look weird but they are ok.
java.nio.channels.GatheringByteChannel and java.nio.channels.ScatteringByteChannel worth a try, although there are quite a bit implementation dependent (native C) to make them useful.
1 Comment
We might try this one since it is apache license
2 Comments
java.nio.ByteBuffer. It's some other class with same name.I would leverage the method ByteBuffer.wrap(). Looking quickly at the implementation by Cisco that Mr. Dean Hiller posted earlier, you could replace the put() by a getWriteBuffer() which would return you a ByteBuffer that wraps the portion within the buffer it can write.
The same logic can be applied for the reading part.
It would have the advantage of not having to compact which could be costly depending on the amount of bytes there is in the ByteBuffer at the cost of complexifying the parsing logic: you may get the first part of your message for the ByteBuffer that wraps the last region of the underlying circular buffer. To get the second part of your message, another read is needed to get the byte array at the beginning of the circular buffer wrapped into another ByteBuffer.