Commit Graph

87 Commits

Author SHA1 Message Date
Trustin Lee
8e1a6c6cf5 Add ByteBuf.maxWritableBytes()
- Fixes #806
2012-12-14 11:49:01 +09:00
Trustin Lee
b47fc77522 Add PooledByteBufAllocator + microbenchmark module
This pull request introduces the new default ByteBufAllocator implementation based on jemalloc, with a some differences:

* Minimum possible buffer capacity is 16 (jemalloc: 2)
* Uses binary heap with random branching (jemalloc: red-black tree)
* No thread-local cache yet (jemalloc has thread-local cache)
* Default page size is 8 KiB (jemalloc: 4 KiB)
* Default chunk size is 16 MiB (jemalloc: 2 MiB)
* Cannot allocate a buffer bigger than the chunk size (jemalloc: possible) because we don't have control over memory layout in Java. A user can work around this issue by creating a composite buffer, but it's not always a feasible option. Although 16 MiB is a pretty big default, a user's handler might need to deal with the bounded buffers when the user wants to deal with a large message.

Also, to ensure the new allocator performs good enough, I wrote a microbenchmark for it and made it a dedicated Maven module. It uses Google's Caliper framework to run and publish the test result (example)

Miscellaneous changes:

* Made some ByteBuf implementations public so that those who implements a new allocator can make use of them.
* Added ByteBufAllocator.compositeBuffer() and its variants.
* ByteBufAllocator.ioBuffer() creates a buffer with 0 capacity.
2012-12-13 22:35:06 +09:00
Trustin Lee
51e6519b67 Replace UnsafeByteBuf with ByteBuf.unsafe() again
* UnsafeByteBuf is gone. I added ByteBuf.unsafe() back.
* To avoid extra instantiation, all ByteBuf implementations implement the ByteBuf.Unsafe interface.
* To hide this implementation detail, all ByteBuf implementations are package-private.
* AbstractByteBuf and SwappedByteBuf are public and they do not implement ByteBuf.Unsafe because they don't need to.
* unwrap() is not an unsafe operation anymore.
* ChannelBuf also has unsafe() and Unsafe. ByteBuf.Unsafe extends ChannelBuf.unsafe(). ChannelBuf.unsafe() provides free() operation so that a user does not need to down-cast the buffer in freeInbound/OutboundBuffer().
2012-12-05 19:28:56 +09:00
Trustin Lee
33c0c89fef Remove unnecessary empty lines 2012-12-03 19:58:13 +09:00
Trustin Lee
e45ab1d182 Fix a checkstyle error 2012-12-02 22:03:11 +09:00
Trustin Lee
5f9090a7f0 Fix invalid memory access in AIO writes
To perform writes in AioSocketChannel, we get a ByteBuffer view of the
outbound buffer and specify it as a parameter when we call
AsynchronousSocketChannel.write().

In most cases, the write() operation is finished immediately.  However,
sometimes, it is scheduled for later execution.  In such a case, there's
a chance for a user's handler to append more data to the outbound
buffer.

When more data is appended to the outbound buffer, the outbound buffer
can expand its capacity by itself.  Changing the capacity of a buffer is
basically made of the following steps:

1. Allocate a larger new internal memory region.
2. Copy the current content of the buffer to the new memory region.
3. Rewire the buffer so that it refers to the new region.
4. Deallocate the old memory region.

Because the old memory region is deallocated at the step 4, the write
operation scheduled later will access the deallocated region, leading
all sort of data corruption or even segfaults.

To prevent this situation, I added suspendIntermediaryDeallocations()
and resumeIntermediaryDeallocations() to UnsafeByteBuf.

AioSocketChannel.doFlushByteBuf() now calls suspendIntermediaryDealloc()
to defer the deallocation of the old memory regions until the completion
handler is notified.
2012-12-02 21:50:33 +09:00
Trustin Lee
bfe2a96505 Fix AssertionError from AsyncSocketChannel.beginRead()
An AssertionError is triggered by a ByteBuf when beginRead() attempts to
access the buffer which has been freed already.  This commit ensures the
buffer is not freed before performing an I/O operation.

To determine if the buffer has been freed, UnsafeByteBuf.isFreed() has
been added.
2012-12-02 20:17:53 +09:00
Trustin Lee
6208c62888 Fix inspector warnings introduced by recent mergences 2012-11-30 23:01:57 +09:00
Trustin Lee
81e2db10fa ByteBufAllocator API w/ ByteBuf perf improvements
This commit introduces a new API for ByteBuf allocation which fixes
issue #643 along with refactoring of ByteBuf for simplicity and better
performance. (see #62)

A user can configure the ByteBufAllocator of a Channel via
ChannelOption.ALLOCATOR or ChannelConfig.get/setAllocator().  The
default allocator is currently UnpooledByteBufAllocator.HEAP_BY_DEFAULT.

To allocate a buffer, do not use Unpooled anymore. do the following:

  ctx.alloc().buffer(...); // allocator chooses the buffer type.
  ctx.alloc().heapBuffer(...);
  ctx.alloc().directBuffer(...);

To deallocate a buffer, use the unsafe free() operation:

  ((UnsafeByteBuf) buf).free();

The following is the list of the relevant changes:

- Add ChannelInboundHandler.freeInboundBuffer() and
  ChannelOutboundHandler.freeOutboundBuffer() to let a user free the
  buffer he or she allocated. ChannelHandler adapter classes implement
  is already, so most users won't need to call free() by themselves.
  freeIn/OutboundBuffer() methods are invoked when a Channel is closed
  and deregistered.

- All ByteBuf by contract must implement UnsafeByteBuf. To access an
  unsafe operation: ((UnsafeByteBuf) buf).internalNioBuffer()

- Replace WrappedByteBuf and ByteBuf.Unsafe with UnsafeByteBuf to
  simplify overall class hierarchy and to avoid unnecesary instantiation
  of Unsafe instances on an unsafe operation.

- Remove buffer reference counting which is confusing

- Instantiate SwappedByteBuf lazily to avoid instantiation cost

- Rename ChannelFutureFactory to ChannelPropertyAccess and move common
  methods between Channel and ChannelHandlerContext there. Also made it
  package-private to hide it from a user.

- Remove unused unsafe operations such as newBuffer()

- Add DetectionUtil.canFreeDirectBuffer() so that an allocator decides
  which buffer type to use safely
2012-11-22 15:10:59 +09:00
Trustin Lee
6f2840193a Fix inspection warnings related with JUnit usage 2012-11-12 12:45:06 +09:00
Trustin Lee
aedf8790c3 Fix various Javadoc issues / Do not use argN parameter names 2012-11-12 12:26:19 +09:00
Trustin Lee
ea4a0e3535 Prefer {@code ...} to <code>...</code> / Fix deprecation warnings 2012-11-12 11:51:23 +09:00
Trustin Lee
b195190b2a Remove an unused import 2012-11-12 11:26:29 +09:00
Trustin Lee
4dce19b814 Replace a variable with a constant wherever possible 2012-11-12 09:43:14 +09:00
Trustin Lee
aa7cd691df Remove redundant 'else' branches. 2012-11-12 09:31:40 +09:00
Trustin Lee
b4f796c5e3 Use 'x' over "x" wherever possible / String.equals("") -> isEmpty() 2012-11-10 08:03:52 +09:00
Trustin Lee
4e0f455e69 Remove methods overridden but identical with the super implementation / Make constructors of abstract classes protected rather than non-sense public
AbstractWrappedByteBuf.capacity(int) should raise a UnsupportedOperationException rather than ReadOnlyBufferException.
2012-11-10 07:10:30 +09:00
Trustin Lee
58ba0de659 Remove unnecessarily qualified static access 2012-11-10 01:32:21 +09:00
Trustin Lee
2ab38d8685 Remove pointless bitwise expressions 2012-11-09 17:26:11 +09:00
Norman Maurer
d293e6c389 [#707] Hopefully now the correct fix for it which also takes the index into account when consolidate 2012-11-04 21:21:26 +01:00
Veebs
36ac52a4bd Port http multipart package. See #709 2012-11-04 13:59:50 +01:00
Norman Maurer
4e3258973f [#707] Fix IndexOutOfBoundsException which could accour when the buffer is consolitated in the middle of an operation 2012-11-03 20:00:48 +01:00
Norman Maurer
122051ba44 Only a few javadocs 2012-10-28 20:45:00 +01:00
Norman Maurer
cbcabaf29b Add support for method chaining to ByteBuf 2012-10-18 08:57:23 +02:00
Norman Maurer
b8ae8be96a Fix IndexOutOfBoundException when using CompositeChannelBuffer and the readerIndex is at the last position and an empty array is passed to read to. See #474 2012-09-22 21:23:58 +02:00
Norman Maurer
5dbb799a92 Merge pull request #554 from jfallows/composite-buffer
Prevent Unpooled.EMPTY_BUFFER from being stored in the composite buffer ...
2012-08-23 22:26:03 -07:00
John Fallows
83c21d70ee Prevent Unpooled.EMPTY_BUFFER from being stored in the composite buffer due to a zero length slice, which causes reference counting problems on subsequent discardReadBytes. 2012-08-19 22:59:49 -07:00
Trustin Lee
df0aee22cb [#540] Add a variant of ByteBuf.ensureWritableBytes() which does not throw an exception 2012-08-20 12:52:38 +09:00
Trustin Lee
aa8a761fe2 Better exception message
.. as advised by @jpinner
2012-08-20 12:30:38 +09:00
Trustin Lee
505e767a09 [#529] ByteBuf.ensureWritableBytes() can trigger IllegalArgumentException
- Remove redundant boundary check in ensureWritableBytes()
- Ensure calculateNewCapacity() never returns the value that exceeds
  maxCapacity
2012-08-17 22:08:36 +09:00
John Fallows
06fd869711 Add support for AIO scattering reads and gathering writes.
o Add ByteBuf.hasNioBuffers() method
 o Promote CompositeByteBuf.nioBuffers() methods to ByteBuf
 o Use ByteBuf.nioBuffers() methods from AioSocketChannel
2012-08-12 17:29:07 -07:00
Trustin Lee
501746aeff Fix an infinite loop in DefaultCompositeByteBuf.setBytes() 2012-08-08 17:42:58 +09:00
Trustin Lee
a2aadef4da Add ByteBuf.Unsafe.discardSomeReadBytes() to reduce discardReadBytes() 2012-08-08 17:34:00 +09:00
norman
f7e0366bae Add nioBuffers() and nioBuffers(..) method which will be used to support gathering writes for the AIO transport. See #492 2012-08-07 15:39:46 +02:00
Trustin Lee
728306b64f Add CompositeByteBuf.consolidate()
- also added test cases that test automatic / full / ranged
  consolidation
2012-08-05 18:32:30 +09:00
Trustin Lee
26e64eb305 Fix IOOBE after buffer truncation / Add CompositeByteBuf.addComponents()
- plus some bug fixes while running unit tests
2012-07-20 13:18:17 +09:00
Trustin Lee
8d813b127c Replace free() with reference counting / Fix SlicedByteBuf.unsafe()
- based on @normanmaurer's feed back
- Added Unpooled.compositeBuffer(int)
2012-07-20 12:33:17 +09:00
Trustin Lee
5a613f379e Make ByteBuf dynamic / Introduce an interface for composite buffers
- Replace ByteBufferBackedByteBuf with DirectByteBuf
- Make DirectByteBuf and HeapByteBuf dynamic
- Remove DynamicByteBuf
- Replace Unpooled.dynamicBuffer() with Unpooled.buffer() and
  directBuffer()
- Remove ByteBufFactory (will be replaced with ByteBufPool later)
- Add ByteBuf.Unsafe (might change in the future)
2012-07-19 20:25:47 +09:00
Trustin Lee
917ed5173e Fix a bug where discardReadBytes() doesn't adjust markers
.. if buffer is empty
2012-07-10 14:23:31 +09:00
Cruz Julian Bishop
b9d16663d9 Fixes javadoc from #414 / #415 (@trustin) 2012-06-30 20:30:56 +10:00
Norman Maurer
27b83a480b Fix checkstyle 2012-06-29 12:49:58 +02:00
Norman Maurer
07095a41f4 Rename method and make it more clear thats an expert method. See #414 #415 2012-06-29 12:28:08 +02:00
Cruz Julian Bishop
c52cb0ea21 Assuming that @trustin will want this changed :) 2012-06-29 19:27:41 +10:00
Cruz Julian Bishop
c55e10c12a Fix a bug where a potential overflow occurs 2012-06-29 13:38:53 +10:00
Cruz Julian Bishop
b11d4fa37a Two tentative last asserts in the test 2012-06-29 13:37:41 +10:00
Cruz Julian Bishop
557f1c85df Little bit more testing 2012-06-29 13:35:14 +10:00
Cruz Julian Bishop
3d9be81377 Provide a basic test for getBufferFor() 2012-06-29 13:31:02 +10:00
Cruz Julian Bishop
e2989719e1 Comply with line width a bit more 2012-06-28 19:34:52 +10:00
Cruz Julian Bishop
a504aa1159 Documentation and checkstyle fixes from @fredericBregier
This is part of #414
2012-06-28 19:33:54 +10:00
Cruz Julian Bishop
42f3a6750a Add documentation and changes to ComposityByteBuf.getBufferFor(index)
Thanks to @kimchy and @fredericBregier
This is part of #414
2012-06-28 19:01:16 +10:00