Move composite buffer methods to Buffer

Motivation:
There is no reason for `compose()` to be an instance method on `BufferAllocator` since the allocator implementation should not influence how this method is implemented.

Modification:
Make `compose()` a static method and move it to the `Buffer` interface.
Also move its companion methods `extendComposite()` and `isComposite()` to the `Buffer` interface.

Result:
The composite buffer methods are now in a more sensible place.

Also: decided _against_ making `extendComposite()` and `isComposite()` instance methods, because the subtle behaviours of `extendComposite()` means it would behave quite differently for non-composite buffers.
Also: `isComposite()` is not an instance method because it relates to the hard-coded and concrete `CompositeBuffer` implementation.
This commit is contained in:
Chris Vest 2021-02-15 17:46:23 +01:00
parent 53ba97edbe
commit 7185a59f7a
6 changed files with 182 additions and 171 deletions

View File

@ -66,7 +66,7 @@ import java.nio.ByteOrder;
* To send a buffer to another thread, the buffer must not have any outstanding borrows.
* That is to say, all {@linkplain #acquire() acquires} must have been paired with a {@link #close()};
* all {@linkplain #slice() slices} must have been closed.
* And if this buffer is a constituent of a {@linkplain BufferAllocator#compose(Deref...) composite buffer},
* And if this buffer is a constituent of a {@linkplain Buffer#compose(BufferAllocator, Deref...) composite buffer},
* then that composite buffer must be closed.
* And if this buffer is itself a composite buffer, then it must own all of its constituent buffers.
* The {@link #isOwned()} method can be used on any buffer to check if it can be sent or not.
@ -103,6 +103,93 @@ import java.nio.ByteOrder;
*
*/
public interface Buffer extends Rc<Buffer>, BufferAccessors {
/**
* Compose the given sequence of buffers and present them as a single buffer.
* <p>
* <strong>Note:</strong> The composite buffer increments the reference count on all the constituent buffers,
* and holds a reference to them until the composite buffer is deallocated.
* This means the constituent buffers must still have their outside-reference count decremented as normal.
* If the buffers are allocated for the purpose of participating in the composite buffer,
* then they should be closed as soon as the composite buffer has been created, like in this example:
* <pre>{@code
* try (Buffer a = allocator.allocate(size);
* Buffer b = allocator.allocate(size)) {
* return allocator.compose(a, b); // Reference counts for 'a' and 'b' incremented here.
* } // Reference count for 'a' and 'b' decremented here; composite buffer now holds the last references.
* }</pre>
* <p>
* {@linkplain Buffer#send() Sending} a composite buffer implies sending all of its constituent buffers.
* For sending to be possible, both the composite buffer itself, and all of its constituent buffers, must be in an
* {@linkplain Rc#isOwned() owned state}.
* This means that the composite buffer must be the only reference to the constituent buffers.
* <p>
* All of the constituent buffers must have the same {@linkplain Buffer#order() byte order}.
* An exception will be thrown if you attempt to compose buffers that have different byte orders,
* and changing the byte order of the constituent buffers so they become inconsistent after construction,
* will result in unspecified behaviour.
* <p>
* The read and write offsets of the constituent buffers must be arranged such that there are no "gaps" when viewed
* as a single connected chunk of memory.
* Specifically, there can be at most one buffer whose write offset is neither zero nor at capacity,
* and all buffers prior to it must have their write offsets at capacity, and all buffers after it must have a write
* offset of zero.
* Likewise, there can be at most one buffer whose read offset is neither zero nor at capacity,
* and all buffers prior to it must have their read offsets at capacity, and all buffers after it must have a read
* offset of zero.
* Furthermore, the sum of the read offsets must be less than or equal to the sum of the write offsets.
* <p>
* Reads and writes to the composite buffer that modifies the read or write offsets, will also modify the relevant
* offsets in the constituent buffers.
* <p>
* It is not a requirement that the buffers have the same size.
* <p>
* It is not a requirement that the buffers are allocated by this allocator, but if
* {@link Buffer#ensureWritable(int)} is called on the composed buffer, and the composed buffer needs to be
* expanded, then this allocator instance will be used for allocation the extra memory.
*
* @param allocator The allocator for the composite buffer. This allocator will be used e.g. to service
* {@link #ensureWritable(int)} calls.
* @param bufs The buffers to compose into a single buffer view.
* @return A buffer composed of, and backed by, the given buffers.
* @throws IllegalArgumentException if the given buffers have an inconsistent
* {@linkplain Buffer#order() byte order}.
*/
@SafeVarargs
static Buffer compose(BufferAllocator allocator, Deref<Buffer>... bufs) {
return new CompositeBuffer(allocator, bufs);
}
/**
* Extend the given composite buffer with the given extension buffer.
* This works as if the extension had originally been included at the end of the list of constituent buffers when
* the composite buffer was created.
* The composite buffer is modified in-place.
*
* @see #compose(BufferAllocator, Deref...)
* @param composite The composite buffer (from a prior {@link #compose(BufferAllocator, Deref...)} call) to extend
* with the given extension buffer.
* @param extension The buffer to extend the composite buffer with.
*/
static void extendComposite(Buffer composite, Buffer extension) {
if (!isComposite(composite)) {
throw new IllegalArgumentException(
"Expected the first buffer to be a composite buffer, " +
"but it is a " + composite.getClass() + " buffer: " + composite + '.');
}
CompositeBuffer compositeBuffer = (CompositeBuffer) composite;
compositeBuffer.extendWith(extension);
}
/**
* Check if the given buffer is a {@linkplain #compose(BufferAllocator, Deref...) composite} buffer or not.
* @param composite The buffer to check.
* @return {@code true} if the given buffer was created with {@link #compose(BufferAllocator, Deref...)},
* {@code false} otherwise.
*/
static boolean isComposite(Buffer composite) {
return composite.getClass() == CompositeBuffer.class;
}
/**
* Change the default byte order of this buffer, and return this buffer.
*

View File

@ -21,6 +21,13 @@ import java.nio.ByteOrder;
* Interface for {@link Buffer} allocators.
*/
public interface BufferAllocator extends AutoCloseable {
/**
* Check that the given {@code size} argument is a valid buffer size, or throw an {@link IllegalArgumentException}.
*
* @param size The size to check.
* @throws IllegalArgumentException if the size is not possitive, or if the size is too big (over ~2 GB) for a
* buffer to accomodate.
*/
static void checkSize(long size) {
if (size < 1) {
throw new IllegalArgumentException("Buffer size must be positive, but was " + size + '.');
@ -59,89 +66,6 @@ public interface BufferAllocator extends AutoCloseable {
return allocate(size).order(order);
}
/**
* Compose the given sequence of buffers and present them as a single buffer.
* <p>
* <strong>Note:</strong> The composite buffer increments the reference count on all the constituent buffers,
* and holds a reference to them until the composite buffer is deallocated.
* This means the constituent buffers must still have their outside-reference count decremented as normal.
* If the buffers are allocated for the purpose of participating in the composite buffer,
* then they should be closed as soon as the composite buffer has been created, like in this example:
* <pre>{@code
* try (Buffer a = allocator.allocate(size);
* Buffer b = allocator.allocate(size)) {
* return allocator.compose(a, b); // Reference counts for 'a' and 'b' incremented here.
* } // Reference count for 'a' and 'b' decremented here; composite buffer now holds the last references.
* }</pre>
* <p>
* {@linkplain Buffer#send() Sending} a composite buffer implies sending all of its constituent buffers.
* For sending to be possible, both the composite buffer itself, and all of its constituent buffers, must be in an
* {@linkplain Rc#isOwned() owned state}.
* This means that the composite buffer must be the only reference to the constituent buffers.
* <p>
* All of the constituent buffers must have the same {@linkplain Buffer#order() byte order}.
* An exception will be thrown if you attempt to compose buffers that have different byte orders,
* and changing the byte order of the constituent buffers so they become inconsistent after construction,
* will result in unspecified behaviour.
* <p>
* The read and write offsets of the constituent buffers must be arranged such that there are no "gaps" when viewed
* as a single connected chunk of memory.
* Specifically, there can be at most one buffer whose write offset is neither zero nor at capacity,
* and all buffers prior to it must have their write offsets at capacity, and all buffers after it must have a write
* offset of zero.
* Likewise, there can be at most one buffer whose read offset is neither zero nor at capacity,
* and all buffers prior to it must have their read offsets at capacity, and all buffers after it must have a read
* offset of zero.
* Furthermore, the sum of the read offsets must be less than or equal to the sum of the write offsets.
* <p>
* Reads and writes to the composite buffer that modifies the read or write offsets, will also modify the relevant
* offsets in the constituent buffers.
* <p>
* It is not a requirement that the buffers have the same size.
* <p>
* It is not a requirement that the buffers are allocated by this allocator, but if
* {@link Buffer#ensureWritable(int)} is called on the composed buffer, and the composed buffer needs to be
* expanded, then this allocator instance will be used for allocation the extra memory.
*
* @param bufs The buffers to compose into a single buffer view.
* @return A buffer composed of, and backed by, the given buffers.
* @throws IllegalArgumentException if the given buffers have an inconsistent
* {@linkplain Buffer#order() byte order}.
*/
default Buffer compose(Deref<Buffer>... bufs) {
return new CompositeBuffer(this, bufs);
}
/**
* Extend the given composite buffer with the given extension buffer.
* This works as if the extension had originally been included at the end of the list of constituent buffers when
* the composite buffer was created.
* The composite buffer is modified in-place.
*
* @see #compose(Deref...)
* @param composite The composite buffer (from a prior {@link #compose(Deref...)} call) to extend with the given
* extension buffer.
* @param extension The buffer to extend the composite buffer with.
*/
static void extend(Buffer composite, Buffer extension) {
if (!isComposite(composite)) {
throw new IllegalArgumentException(
"Expected the first buffer to be a composite buffer, " +
"but it is a " + composite.getClass() + " buffer: " + composite + '.');
}
CompositeBuffer buf = (CompositeBuffer) composite;
buf.extendWith(extension);
}
/**
* Check if the given buffer is a {@linkplain #compose(Deref...) composite} buffer or not.
* @param composite The buffer to check.
* @return {@code true} if the given buffer was created with {@link #compose(Deref...)}, {@code false} otherwise.
*/
static boolean isComposite(Buffer composite) {
return composite.getClass() == CompositeBuffer.class;
}
/**
* Close this allocator, freeing all of its internal resources. It is not specified if the allocator can still be
* used after this method has been called on it.

View File

@ -123,7 +123,7 @@ public class BufferTest {
int half = size / 2;
try (Buffer firstHalf = a.allocate(half);
Buffer secondHalf = b.allocate(size - half)) {
return a.compose(firstHalf, secondHalf);
return Buffer.compose(a, firstHalf, secondHalf);
}
}
@ -147,7 +147,7 @@ public class BufferTest {
try (Buffer a = alloc.allocate(part);
Buffer b = alloc.allocate(part);
Buffer c = alloc.allocate(size - part * 2)) {
return alloc.compose(a, b, c);
return Buffer.compose(alloc, a, b, c);
}
}
@ -186,7 +186,7 @@ public class BufferTest {
if (size < 2) {
return allocator.allocate(size);
}
var buf = allocator.compose();
var buf = Buffer.compose(allocator);
buf.ensureWritable(size);
return buf;
}
@ -426,8 +426,8 @@ public class BufferTest {
assertThrows(IllegalStateException.class, () -> buf.copyInto(0, target, 0, 1));
assertThrows(IllegalStateException.class, () -> buf.copyInto(0, new byte[1], 0, 1));
assertThrows(IllegalStateException.class, () -> buf.copyInto(0, ByteBuffer.allocate(1), 0, 1));
if (BufferAllocator.isComposite(buf)) {
assertThrows(IllegalStateException.class, () -> BufferAllocator.extend(buf, target));
if (Buffer.isComposite(buf)) {
assertThrows(IllegalStateException.class, () -> Buffer.extendComposite(buf, target));
}
}
@ -890,7 +890,7 @@ public class BufferTest {
assertEquals(0, slice.capacity()); // We haven't written anything, so the slice is empty.
int sliceBorrows = slice.countBorrows();
assertEquals(borrows + 2, buf.countBorrows());
try (Buffer ignored1 = allocator.compose(buf, slice)) {
try (Buffer ignored1 = Buffer.compose(allocator, buf, slice)) {
assertEquals(borrows + 3, buf.countBorrows());
// Note: Slice is empty; not acquired by the composite buffer.
assertEquals(sliceBorrows, slice.countBorrows());
@ -1033,7 +1033,7 @@ public class BufferTest {
int second = size - first;
try (var bufFirst = a.allocate(first);
var bufSecond = b.allocate(second)) {
return a.compose(bufFirst, bufSecond);
return Buffer.compose(a, bufFirst, bufSecond);
}
});
}
@ -1049,7 +1049,7 @@ public class BufferTest {
int second = size - first;
try (var bufFirst = a.allocate(first);
var bufSecond = b.allocate(second)) {
return a.compose(bufFirst, bufSecond);
return Buffer.compose(a, bufFirst, bufSecond);
}
});
}
@ -1065,7 +1065,7 @@ public class BufferTest {
int second = size - first;
try (var bufFirst = a.allocate(first);
var bufSecond = b.allocate(second)) {
return a.compose(bufFirst, bufSecond);
return Buffer.compose(a, bufFirst, bufSecond);
}
});
}
@ -1081,7 +1081,7 @@ public class BufferTest {
int second = size - first;
try (var bufFirst = a.allocate(first);
var bufSecond = b.allocate(second)) {
return a.compose(bufFirst, bufSecond);
return Buffer.compose(a, bufFirst, bufSecond);
}
});
}
@ -1098,7 +1098,7 @@ public class BufferTest {
int second = size - first;
try (var bufFirst = a.allocate(first);
var bufSecond = b.allocate(second)) {
return scope.add(a.compose(bufFirst, bufSecond)).writerOffset(size).slice();
return scope.add(Buffer.compose(a, bufFirst, bufSecond)).writerOffset(size).slice();
}
});
}
@ -1115,7 +1115,7 @@ public class BufferTest {
int second = size - first;
try (var bufFirst = a.allocate(first);
var bufSecond = b.allocate(second)) {
return scope.add(a.compose(bufFirst, bufSecond)).writerOffset(size).slice();
return scope.add(Buffer.compose(a, bufFirst, bufSecond)).writerOffset(size).slice();
}
});
}
@ -1132,7 +1132,7 @@ public class BufferTest {
int second = size - first;
try (var bufFirst = a.allocate(first);
var bufSecond = b.allocate(second)) {
return scope.add(a.compose(bufFirst, bufSecond)).writerOffset(size).slice();
return scope.add(Buffer.compose(a, bufFirst, bufSecond)).writerOffset(size).slice();
}
});
}
@ -1149,7 +1149,7 @@ public class BufferTest {
int second = size - first;
try (var bufFirst = a.allocate(first);
var bufSecond = b.allocate(second)) {
return scope.add(a.compose(bufFirst, bufSecond)).writerOffset(size).slice();
return scope.add(Buffer.compose(a, bufFirst, bufSecond)).writerOffset(size).slice();
}
});
}
@ -1625,7 +1625,7 @@ public class BufferTest {
try (Buffer b = allocator.allocate(8)) {
assertTrue(a.isOwned());
assertTrue(b.isOwned());
composite = allocator.compose(a, b);
composite = Buffer.compose(allocator, a, b);
assertFalse(composite.isOwned());
assertFalse(a.isOwned());
assertFalse(b.isOwned());
@ -1643,13 +1643,13 @@ public class BufferTest {
public void compositeBuffersCannotHaveDuplicateComponents() {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer a = allocator.allocate(4)) {
var e = assertThrows(IllegalArgumentException.class, () -> allocator.compose(a, a));
var e = assertThrows(IllegalArgumentException.class, () -> Buffer.compose(allocator, a, a));
assertThat(e).hasMessageContaining("duplicate");
try (Buffer composite = allocator.compose(a)) {
try (Buffer composite = Buffer.compose(allocator, a)) {
a.close();
try {
e = assertThrows(IllegalArgumentException.class, () -> BufferAllocator.extend(composite, a));
e = assertThrows(IllegalArgumentException.class, () -> Buffer.extendComposite(composite, a));
assertThat(e).hasMessageContaining("duplicate");
} finally {
a.acquire();
@ -1661,7 +1661,7 @@ public class BufferTest {
@Test
public void compositeBufferFromSends() {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer composite = allocator.compose(
Buffer composite = Buffer.compose(allocator,
allocator.allocate(8).send(),
allocator.allocate(8).send(),
allocator.allocate(8).send())) {
@ -1674,18 +1674,18 @@ public class BufferTest {
public void compositeBufferMustNotBeAllowedToContainThemselves() {
try (BufferAllocator allocator = BufferAllocator.heap()) {
Buffer a = allocator.allocate(4);
Buffer buf = allocator.compose(a);
Buffer buf = Buffer.compose(allocator, a);
try (buf; a) {
a.close();
try {
assertThrows(IllegalArgumentException.class, () -> BufferAllocator.extend(buf, buf));
assertThrows(IllegalArgumentException.class, () -> Buffer.extendComposite(buf, buf));
assertTrue(buf.isOwned());
try (Buffer composite = allocator.compose(buf)) {
try (Buffer composite = Buffer.compose(allocator, buf)) {
// the composing increments the reference count of constituent buffers...
// counter-act this so it can be extended:
a.close(); // buf is now owned so it can be extended.
try {
assertThrows(IllegalArgumentException.class, () -> BufferAllocator.extend(buf, composite));
assertThrows(IllegalArgumentException.class, () -> Buffer.extendComposite(buf, composite));
} finally {
a.acquire(); // restore the reference count to align with our try-with-resources structure.
}
@ -1707,7 +1707,7 @@ public class BufferTest {
assertThrows(IllegalStateException.class, () -> slice.ensureWritable(1));
assertThrows(IllegalStateException.class, () -> buf.ensureWritable(1));
}
try (Buffer compose = allocator.compose(buf)) {
try (Buffer compose = Buffer.compose(allocator, buf)) {
assertThrows(IllegalStateException.class, () -> compose.ensureWritable(1));
assertThrows(IllegalStateException.class, () -> buf.ensureWritable(1));
}
@ -1766,7 +1766,7 @@ public class BufferTest {
@Test
public void ensureWritableMustExpandCapacityOfEmptyCompositeBuffer() {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer buf = allocator.compose()) {
Buffer buf = Buffer.compose(allocator)) {
assertThat(buf.writableBytes()).isEqualTo(0);
buf.ensureWritable(8);
assertThat(buf.writableBytes()).isGreaterThanOrEqualTo(8);
@ -1799,7 +1799,7 @@ public class BufferTest {
try (BufferAllocator allocator = fixture.createAllocator()) {
Buffer composite;
try (Buffer a = allocator.allocate(4, BIG_ENDIAN)) {
composite = allocator.compose(a);
composite = Buffer.compose(allocator, a);
}
try (composite) {
composite.writeInt(0x01020304);
@ -1816,7 +1816,7 @@ public class BufferTest {
try (BufferAllocator allocator = fixture.createAllocator()) {
Buffer composite;
try (Buffer a = allocator.allocate(4, LITTLE_ENDIAN)) {
composite = allocator.compose(a);
composite = Buffer.compose(allocator, a);
}
try (composite) {
composite.writeInt(0x05060708);
@ -1885,7 +1885,7 @@ public class BufferTest {
@Test
public void emptyCompositeBufferMustUseNativeByteOrder() {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer composite = allocator.compose()) {
Buffer composite = Buffer.compose(allocator)) {
assertThat(composite.order()).isEqualTo(ByteOrder.nativeOrder());
}
}
@ -1895,7 +1895,7 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer a = allocator.allocate(8);
Buffer b = allocator.allocate(8)) {
var exc = assertThrows(IllegalArgumentException.class, () -> BufferAllocator.extend(a, b));
var exc = assertThrows(IllegalArgumentException.class, () -> Buffer.extendComposite(a, b));
assertThat(exc).hasMessageContaining("Expected").hasMessageContaining("composite");
}
}
@ -1905,9 +1905,9 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer a = allocator.allocate(8);
Buffer b = allocator.allocate(8);
Buffer composed = allocator.compose(a)) {
Buffer composed = Buffer.compose(allocator, a)) {
try (Buffer ignore = composed.acquire()) {
var exc = assertThrows(IllegalStateException.class, () -> BufferAllocator.extend(composed, b));
var exc = assertThrows(IllegalStateException.class, () -> Buffer.extendComposite(composed, b));
assertThat(exc).hasMessageContaining("owned");
}
}
@ -1918,11 +1918,11 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap()) {
Buffer composite;
try (Buffer a = allocator.allocate(8)) {
composite = allocator.compose(a);
composite = Buffer.compose(allocator, a);
}
try (composite) {
var exc = assertThrows(IllegalArgumentException.class,
() -> BufferAllocator.extend(composite, composite));
() -> Buffer.extendComposite(composite, composite));
assertThat(exc).hasMessageContaining("cannot be extended");
}
}
@ -1931,20 +1931,20 @@ public class BufferTest {
@Test
public void extendingWithZeroCapacityBufferHasNoEffect() {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer composite = allocator.compose()) {
BufferAllocator.extend(composite, composite);
Buffer composite = Buffer.compose(allocator)) {
Buffer.extendComposite(composite, composite);
assertThat(composite.capacity()).isZero();
assertThat(composite.countComponents()).isZero();
}
try (BufferAllocator allocator = BufferAllocator.heap()) {
Buffer a = allocator.allocate(1);
Buffer composite = allocator.compose(a);
Buffer composite = Buffer.compose(allocator, a);
a.close();
assertTrue(composite.isOwned());
assertThat(composite.capacity()).isOne();
assertThat(composite.countComponents()).isOne();
try (Buffer b = allocator.compose()) {
BufferAllocator.extend(composite, b);
try (Buffer b = Buffer.compose(allocator)) {
Buffer.extendComposite(composite, b);
}
assertTrue(composite.isOwned());
assertThat(composite.capacity()).isOne();
@ -1955,18 +1955,18 @@ public class BufferTest {
@Test
public void extendingCompositeBufferWithNullMustThrow() {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer composite = allocator.compose()) {
assertThrows(NullPointerException.class, () -> BufferAllocator.extend(composite, null));
Buffer composite = Buffer.compose(allocator)) {
assertThrows(NullPointerException.class, () -> Buffer.extendComposite(composite, null));
}
}
@Test
public void extendingCompositeBufferMustIncreaseCapacityByGivenBigEndianBuffer() {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer composite = allocator.compose()) {
Buffer composite = Buffer.compose(allocator)) {
assertThat(composite.capacity()).isZero();
try (Buffer buf = allocator.allocate(8, BIG_ENDIAN)) {
BufferAllocator.extend(composite, buf);
Buffer.extendComposite(composite, buf);
}
assertThat(composite.capacity()).isEqualTo(8);
composite.writeLong(0x0102030405060708L);
@ -1977,10 +1977,10 @@ public class BufferTest {
@Test
public void extendingCompositeBufferMustIncreaseCapacityByGivenLittleEndianBuffer() {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer composite = allocator.compose()) {
Buffer composite = Buffer.compose(allocator)) {
assertThat(composite.capacity()).isZero();
try (Buffer buf = allocator.allocate(8, LITTLE_ENDIAN)) {
BufferAllocator.extend(composite, buf);
Buffer.extendComposite(composite, buf);
}
assertThat(composite.capacity()).isEqualTo(8);
composite.writeLong(0x0102030405060708L);
@ -1993,11 +1993,11 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap()) {
Buffer composite;
try (Buffer a = allocator.allocate(8, BIG_ENDIAN)) {
composite = allocator.compose(a);
composite = Buffer.compose(allocator, a);
}
try (composite) {
try (Buffer b = allocator.allocate(8, LITTLE_ENDIAN)) {
var exc = assertThrows(IllegalArgumentException.class, () -> BufferAllocator.extend(composite, b));
var exc = assertThrows(IllegalArgumentException.class, () -> Buffer.extendComposite(composite, b));
assertThat(exc).hasMessageContaining("byte order");
}
}
@ -2009,11 +2009,11 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap()) {
Buffer composite;
try (Buffer a = allocator.allocate(8, LITTLE_ENDIAN)) {
composite = allocator.compose(a);
composite = Buffer.compose(allocator, a);
}
try (composite) {
try (Buffer b = allocator.allocate(8, BIG_ENDIAN)) {
var exc = assertThrows(IllegalArgumentException.class, () -> BufferAllocator.extend(composite, b));
var exc = assertThrows(IllegalArgumentException.class, () -> Buffer.extendComposite(composite, b));
assertThat(exc).hasMessageContaining("byte order");
}
}
@ -2023,9 +2023,9 @@ public class BufferTest {
@Test
public void emptyCompositeBufferMustAllowExtendingWithBufferWithBigEndianByteOrder() {
try (BufferAllocator allocator = BufferAllocator.heap()) {
try (Buffer composite = allocator.compose()) {
try (Buffer composite = Buffer.compose(allocator)) {
try (Buffer b = allocator.allocate(8, BIG_ENDIAN)) {
BufferAllocator.extend(composite, b);
Buffer.extendComposite(composite, b);
assertThat(composite.order()).isEqualTo(BIG_ENDIAN);
}
}
@ -2035,9 +2035,9 @@ public class BufferTest {
@Test
public void emptyCompositeBufferMustAllowExtendingWithBufferWithLittleEndianByteOrder() {
try (BufferAllocator allocator = BufferAllocator.heap()) {
try (Buffer composite = allocator.compose()) {
try (Buffer composite = Buffer.compose(allocator)) {
try (Buffer b = allocator.allocate(8, LITTLE_ENDIAN)) {
BufferAllocator.extend(composite, b);
Buffer.extendComposite(composite, b);
assertThat(composite.order()).isEqualTo(LITTLE_ENDIAN);
}
}
@ -2047,9 +2047,9 @@ public class BufferTest {
@Test
public void emptyCompositeBufferMustAllowExtendingWithReadOnlyBuffer() {
try (BufferAllocator allocator = BufferAllocator.heap()) {
try (Buffer composite = allocator.compose()) {
try (Buffer composite = Buffer.compose(allocator)) {
try (Buffer b = allocator.allocate(8).readOnly(true)) {
BufferAllocator.extend(composite, b);
Buffer.extendComposite(composite, b);
assertTrue(composite.readOnly());
}
}
@ -2061,13 +2061,13 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap()) {
Buffer composite;
try (Buffer a = allocator.allocate(8)) {
composite = allocator.compose(a);
composite = Buffer.compose(allocator, a);
}
try (composite) {
composite.writeLong(0);
try (Buffer b = allocator.allocate(8)) {
b.writeInt(1);
BufferAllocator.extend(composite, b);
Buffer.extendComposite(composite, b);
assertThat(composite.capacity()).isEqualTo(16);
assertThat(composite.writerOffset()).isEqualTo(12);
}
@ -2080,16 +2080,16 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap()) {
Buffer composite;
try (Buffer a = allocator.allocate(8)) {
composite = allocator.compose(a);
composite = Buffer.compose(allocator, a);
}
try (composite) {
composite.writeInt(0);
try (Buffer b = allocator.allocate(8)) {
b.writeInt(1);
var exc = assertThrows(IllegalArgumentException.class, () -> BufferAllocator.extend(composite, b));
var exc = assertThrows(IllegalArgumentException.class, () -> Buffer.extendComposite(composite, b));
assertThat(exc).hasMessageContaining("unwritten gap");
b.writerOffset(0);
BufferAllocator.extend(composite, b);
Buffer.extendComposite(composite, b);
assertThat(composite.capacity()).isEqualTo(16);
assertThat(composite.writerOffset()).isEqualTo(4);
}
@ -2102,7 +2102,7 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap()) {
Buffer composite;
try (Buffer a = allocator.allocate(8)) {
composite = allocator.compose(a);
composite = Buffer.compose(allocator, a);
}
try (composite) {
composite.writeLong(0);
@ -2110,7 +2110,7 @@ public class BufferTest {
try (Buffer b = allocator.allocate(8)) {
b.writeInt(1);
b.readInt();
BufferAllocator.extend(composite, b);
Buffer.extendComposite(composite, b);
assertThat(composite.capacity()).isEqualTo(16);
assertThat(composite.writerOffset()).isEqualTo(12);
}
@ -2123,7 +2123,7 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap()) {
Buffer composite;
try (Buffer a = allocator.allocate(8)) {
composite = allocator.compose(a);
composite = Buffer.compose(allocator, a);
}
try (composite) {
composite.writeLong(0);
@ -2131,10 +2131,10 @@ public class BufferTest {
try (Buffer b = allocator.allocate(8)) {
b.writeInt(1);
b.readInt();
var exc = assertThrows(IllegalArgumentException.class, () -> BufferAllocator.extend(composite, b));
var exc = assertThrows(IllegalArgumentException.class, () -> Buffer.extendComposite(composite, b));
assertThat(exc).hasMessageContaining("unread gap");
b.readerOffset(0);
BufferAllocator.extend(composite, b);
Buffer.extendComposite(composite, b);
assertThat(composite.capacity()).isEqualTo(16);
assertThat(composite.writerOffset()).isEqualTo(12);
assertThat(composite.readerOffset()).isEqualTo(4);
@ -2148,7 +2148,7 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer a = allocator.allocate(4, BIG_ENDIAN);
Buffer b = allocator.allocate(4, LITTLE_ENDIAN)) {
assertThrows(IllegalArgumentException.class, () -> allocator.compose(a, b));
assertThrows(IllegalArgumentException.class, () -> Buffer.compose(allocator, a, b));
}
}
@ -2319,7 +2319,7 @@ public class BufferTest {
@Test
public void bifurcateOnEmptyBigEndianCompositeBuffer() {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer buf = allocator.compose().order(BIG_ENDIAN)) {
Buffer buf = Buffer.compose(allocator).order(BIG_ENDIAN)) {
verifyBifurcateEmptyCompositeBuffer(buf);
}
}
@ -2327,7 +2327,7 @@ public class BufferTest {
@Test
public void bifurcateOnEmptyLittleEndianCompositeBuffer() {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer buf = allocator.compose().order(LITTLE_ENDIAN)) {
Buffer buf = Buffer.compose(allocator).order(LITTLE_ENDIAN)) {
verifyBifurcateEmptyCompositeBuffer(buf);
}
}
@ -2519,7 +2519,7 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer a = allocator.allocate(4).readOnly(true);
Buffer b = allocator.allocate(4).readOnly(true);
Buffer composite = allocator.compose(a, b)) {
Buffer composite = Buffer.compose(allocator, a, b)) {
assertTrue(composite.readOnly());
verifyWriteInaccessible(composite);
}
@ -2542,7 +2542,7 @@ public class BufferTest {
@Test
public void readOnlyBufferMustRemainReadOnlyAfterSendForEmptyCompositeBuffer() {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer buf = allocator.compose()) {
Buffer buf = Buffer.compose(allocator)) {
buf.readOnly(true);
var send = buf.send();
try (Buffer receive = send.receive()) {
@ -2609,10 +2609,10 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap();
Buffer a = allocator.allocate(8).readOnly(true);
Buffer b = allocator.allocate(8)) {
assertThrows(IllegalArgumentException.class, () -> allocator.compose(a, b));
assertThrows(IllegalArgumentException.class, () -> allocator.compose(b, a));
assertThrows(IllegalArgumentException.class, () -> allocator.compose(a, b, a));
assertThrows(IllegalArgumentException.class, () -> allocator.compose(b, a, b));
assertThrows(IllegalArgumentException.class, () -> Buffer.compose(allocator, a, b));
assertThrows(IllegalArgumentException.class, () -> Buffer.compose(allocator, b, a));
assertThrows(IllegalArgumentException.class, () -> Buffer.compose(allocator, a, b, a));
assertThrows(IllegalArgumentException.class, () -> Buffer.compose(allocator, b, a, b));
}
}
@ -2621,10 +2621,10 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap()) {
Buffer composite;
try (Buffer a = allocator.allocate(8)) {
composite = allocator.compose(a);
composite = Buffer.compose(allocator, a);
}
try (composite; Buffer b = allocator.allocate(8).readOnly(true)) {
assertThrows(IllegalArgumentException.class, () -> BufferAllocator.extend(composite, b));
assertThrows(IllegalArgumentException.class, () -> Buffer.extendComposite(composite, b));
}
}
}
@ -2634,10 +2634,10 @@ public class BufferTest {
try (BufferAllocator allocator = BufferAllocator.heap()) {
Buffer composite;
try (Buffer a = allocator.allocate(8).readOnly(true)) {
composite = allocator.compose(a);
composite = Buffer.compose(allocator, a);
}
try (composite; Buffer b = allocator.allocate(8)) {
assertThrows(IllegalArgumentException.class, () -> BufferAllocator.extend(composite, b));
assertThrows(IllegalArgumentException.class, () -> Buffer.extendComposite(composite, b));
}
}
}
@ -2713,8 +2713,8 @@ public class BufferTest {
try (Buffer a = allocator.allocate(8);
Buffer b = allocator.allocate(8);
Buffer c = allocator.allocate(8);
Buffer x = allocator.compose(b, c)) {
buf = allocator.compose(a, x);
Buffer x = Buffer.compose(allocator, b, c)) {
buf = Buffer.compose(allocator, a, x);
}
assertThat(buf.countComponents()).isEqualTo(3);
assertThat(buf.countReadableComponents()).isZero();
@ -2794,7 +2794,7 @@ public class BufferTest {
a.writeInt(1);
b.writeInt(2);
c.writeInt(3);
composite = allocator.compose(a, b, c);
composite = Buffer.compose(allocator, a, b, c);
}
var list = new LinkedList<Integer>(List.of(1, 2, 3));
int count = composite.forEachReadable(0, (index, component) -> {
@ -2831,7 +2831,7 @@ public class BufferTest {
a.writeInt(1);
b.writeInt(2);
c.writeInt(3);
composite = allocator.compose(a, b, c);
composite = Buffer.compose(allocator, a, b, c);
}
int readPos = composite.readerOffset();
int writePos = composite.writerOffset();
@ -2869,7 +2869,7 @@ public class BufferTest {
try (Buffer a = allocator.allocate(4);
Buffer b = allocator.allocate(4);
Buffer c = allocator.allocate(4)) {
buf = allocator.compose(a, b, c);
buf = Buffer.compose(allocator, a, b, c);
}
int i = 1;
while (buf.writableBytes() > 0) {
@ -2942,7 +2942,7 @@ public class BufferTest {
try (Buffer a = allocator.allocate(8);
Buffer b = allocator.allocate(8);
Buffer c = allocator.allocate(8)) {
buf = allocator.compose(a, b, c);
buf = Buffer.compose(allocator, a, b, c);
}
buf.order(BIG_ENDIAN);
buf.forEachWritable(0, (index, component) -> {

View File

@ -62,14 +62,14 @@ public class ByteIterationBenchmark {
allocator = BufferAllocator.heap();
try (var a = allocator.allocate(SIZE / 2);
var b = allocator.allocate(SIZE / 2)) {
buf = allocator.compose(a, b);
buf = Buffer.compose(allocator, a, b);
}
break;
case "composite-direct":
allocator = BufferAllocator.direct();
try (var a = allocator.allocate(SIZE / 2);
var b = allocator.allocate(SIZE / 2)) {
buf = allocator.compose(a, b);
buf = Buffer.compose(allocator, a, b);
}
break;
default:

View File

@ -44,7 +44,7 @@ public final class ComposingAndSlicingExample {
private static Buffer createBigBuffer(BufferAllocator allocator) {
try (Scope scope = new Scope()) {
return allocator.compose(
return Buffer.compose(allocator,
scope.add(allocator.allocate(64)),
scope.add(allocator.allocate(64)),
scope.add(allocator.allocate(64)),

View File

@ -37,7 +37,7 @@ public final class FileCopyExample {
try (BufferAllocator allocator = BufferAllocator.pooledDirect();
var input = FileChannel.open(Path.of("/dev/urandom"), READ);
var output = FileChannel.open(Path.of("random.bin"), CREATE, TRUNCATE_EXISTING, WRITE)) {
Send<Buffer> done = allocator.compose().send();
Send<Buffer> done = Buffer.compose(allocator).send();
var reader = executor.submit(() -> {
for (int i = 0; i < 1024; i++) {