Yes, it has taken me a while to get that CompositeIoBuffer written. :-) In any case it looks like the discussion has moved on past needing a composite interface. But since I've already sketched something up I may as well post it anyway!
http://pastebin.com/f3c9c5f8d I've cut a lot of corners, but hopefully the idea is still clear. In particular the Cursor (or iterator) provides an abstraction for a position within a ByteArray. A ByteArray only provides absolute access methods, and its Cursor provides only relative access methods. For consistency they should each have the same set of operations. A Cursor could also be Cloneable, so that users could emulate position/mark functionality if they want. In an implementation backed by a ByteBuffer, all absolute methods are fast, and for simplicity its Cursor just delegates to the absolute methods. In a composite implementation backed by a sequence of other ByteArrays, absolute methods are slow and relative methods are fast. And for simplicity, all absolute methods just create a cursor and call the equivalent relative method. Cheers Rich On Tue, Apr 29, 2008 at 5:43 PM, "이희승 (Trustin Lee) <[EMAIL PROTECTED]> wrote: > Hi Rich, > > Good to see you back in the mailing list. It seems like you were > spending a fair amount of time with DIRMINA-489. :) > > Rich Dougherty wrote: > <snip/> > > - However, in a composite implementation, where the actual byte storage > > is spread over a sequence of underlying objects, there may be a cost > > associated with random access. Since a lot of real access is in fact > > going to be sequential, it might make sense to provide something like an > > "iterator" to efficiently support this usage pattern. > > > > In my (unfinished) CompositeIoBuffer implementation, I used a private > > iterator class to implement the buffer's position and mark. This made > > them a lot easier to use, since it encapsulated away the details of how > > to efficiently traverse the component buffers. > > Could you share your iterator interface? I think it's worthwhile to > review, too. I find myself start to like pastebin.com because they keep > the code for a month. :) > > > - Does the ByteArray interface provide operations for expansion, or > > would this be subclass-specific behaviour? I'm guessing expansion is a > > subclass-specific, since the javadoc says that a ByteArray is fixed > size. > > We could implement a special list of ByteArrays for expansion. For > example, it could be something similar to Queue<ByteArray> with getter > and putter methods. > > CompositeByteArray could remain fixed-size and be provided with a list > of ByteArrays when it is constructed. WDYT? > > I initially thought we don't even need a CompositeByteArray, but I found > it has its worth, especially with framing. A framing filter could > assemble/frag an arbitrary number of ByteArrays into an arbitrary number > of ByteArrays (i.e. N:M association). CompositeByteArray is essential > to support this use case. For example, the current text line decoder > could benefit from CompositeByteArray. Let's assume that the decoder > received "AB" and "CD\nE". The decoder (or framing filter) could > generate a CompositeByteArray of "AB" and PartialByteArray("CD\nE", 0, 2). > > > - Were you thinking that asByteBuffer() would return the ByteArray's > > backing ByteBuffer, or on implementing a version of ByteBuffer that > > delegates to the underlying ByteArray? > > > > If it's the former, then it's probably worth thinking about the desired > > semantics for a CompositeByteArray. Do we need to guarantee that > > modification of the returned array will always modify the underlying > > ByteArray? I think it would be possible to /almost/ implement this for a > > CompositeByteArray, i.e. by first copying all component buffers into a > > single buffer, then returning its ByteBuffer. But if we then added > > another buffer to the CompositeByteArray (expanding it) and called > > asByteBuffer() again, we'd need to create another ByteBuffer. So we'd > > now have two different ByteBuffers returned by this method, and the > > first ByteBuffer would become "disconnected" from the underlying > > ByteArray. I hope that made sense! > > You are right. If we are going to implement CompositeByteArray, we have > to think a few things again: > > 1) we need to think again about asByteBuffer() method. asByteBuffer() > method will be used as often as CompositeByteArray, and therefore > copying on demand will kill the original intention of CompositeByteArray > - zero-copy. It should return an array of ByteBuffer(s), or something > different should be provided. So.. that's why I want to know how you > implemented the iterator. :) > > 2) we need to add a minimal set of getter and setter methods such as > getLong(index) and setInt(index, value), because offset calculation in > CompositeByteArray is complicated so we can't just call get() or set() > methods four to eight times - the overhead will not be negligible. > > What I can think of right now is something like this: > > ByteArray b = ...; > ByteArrayPointer p = b.newPointer(8); > > assert p.index() == 8; > // same with value = b.getInt(8); and p.index(p.index() + 4); > long value = p.getInt(); > assert p.index() == 12; > > ByteArrayPointer is basically a wrapper of the ByteArray which provides > stateful properties such as current index and byte order. > > So.. the introduction of CompositeByteArray makes direct exposure of NIO > ByteBuffers somewhat difficult, although workarounds (disconnected > buffer by on-demand/manual copy or returns an array of buffers) are > available. > > WDYT? > > Thanks, > -- > Trustin Lee - Principal Software Engineer, JBoss, Red Hat > -- > what we call human nature is actually human habit > -- > http://gleamynode.net/ > >
