Introduce a Buf interface

The intent is that this will hide the BBuf implementation in the long run.
For the time being, it highlights an issue with the Rc family of types and their generics, and specifically how they are complicated to compose with other interfaces.
This commit is contained in:
Chris Vest 2020-08-24 17:13:04 +02:00
parent 7ab05dae7a
commit 35bde75d52
4 changed files with 73 additions and 15 deletions

View File

@ -5,9 +5,8 @@ import jdk.incubator.foreign.MemorySegment;
import static io.netty.buffer.b2.BBuf.*;
/**
* Interface for {@link BBuf} allocators.
* Interface for {@link Buf} allocators.
*/
@SuppressWarnings("InterfaceMayBeAnnotatedFunctional")
public interface Allocator extends AutoCloseable {
static void checkSize(long size) {
if (size < 1) {
@ -22,13 +21,13 @@ public interface Allocator extends AutoCloseable {
}
/**
* Allocate a {@link BBuf} of the given size in bytes. This method may throw an {@link OutOfMemoryError} if there is
* not enough free memory available to allocate a {@link BBuf} of the requested size.
* Allocate a {@link Buf} of the given size in bytes. This method may throw an {@link OutOfMemoryError} if there is
* not enough free memory available to allocate a {@link Buf} of the requested size.
*
* @param size The size of {@link BBuf} to allocate.
* @return The newly allocated {@link BBuf}.
* @param size The size of {@link Buf} to allocate.
* @return The newly allocated {@link Buf}.
*/
BBuf allocate(long size);
<T extends Buf<T>> T allocate(long size);
/**
* Close this allocator, freeing all of its internal resources. It is not specified if the allocator can still be
@ -52,7 +51,7 @@ public interface Allocator extends AutoCloseable {
static Allocator direct() {
return new Allocator() {
@Override
public BBuf allocate(long size) {
public Buf allocate(long size) {
checkSize(size);
var segment = MemorySegment.allocateNative(size);
Statics.MEM_USAGE_NATIVE.add(size);

View File

@ -7,7 +7,7 @@ import jdk.incubator.foreign.MemorySegment;
import static io.netty.buffer.b2.Statics.*;
public class BBuf extends RcSupport<BBuf> {
public class BBuf extends RcSupport<BBuf> implements Buf<BBuf> {
static final Drop<BBuf> NO_DROP = buf -> {};
static final Drop<BBuf> SEGMENT_CLOSE = buf -> buf.segment.close();
static final Drop<BBuf> SEGMENT_CLOSE_NATIVE = buf -> {
@ -23,16 +23,27 @@ public class BBuf extends RcSupport<BBuf> {
this.segment = segment;
}
@Override
public int readerIndex() {
return read;
}
@Override
public BBuf readerIndex(int index) {
if (index < 0 || segment.byteSize() <= index) {
throw new IndexOutOfBoundsException(
"Index " + index + " is out of bounds: [0 to " + segment.byteSize() + "].");
}
checkIndexBounds(index);
read = index;
return this;
}
public BBuf touch() {
@Override
public int writerIndex() {
return write;
}
@Override
public BBuf writerIndex(int index) {
checkIndexBounds(index);
write = index;
return this;
}
@ -100,4 +111,15 @@ public class BBuf extends RcSupport<BBuf> {
}
};
}
private void checkIndexBounds(int index) {
if (index < 0 || segment.byteSize() <= index) {
throw indexOutOfBounds(index);
}
}
private IndexOutOfBoundsException indexOutOfBounds(int index) {
return new IndexOutOfBoundsException(
"Index " + index + " is out of bounds: [0 to " + segment.byteSize() + "].");
}
}

View File

@ -0,0 +1,37 @@
package io.netty.buffer.b2;
/**
* A reference counted buffer API with separate reader and writer indexes.
* @param <T> The concrete runtime buffer type.
*/
public interface Buf<T extends Buf<T>> extends Rc<T> {
/**
* Get the current reader index. The next read will happen from this byte index into the buffer.
*
* @return The current reader index.
*/
int readerIndex();
/**
* Set the reader index. Make the next read happen from the given index.
*
* @param index The reader index to set.
* @return This Buf.
*/
T readerIndex(int index);
/**
* Get the current writer index. The next write will happen at this byte index into the byffer.
*
* @return The current writer index.
*/
int writerIndex();
/**
* Set the writer index. Make the next write happen at the given index.
*
* @param index The writer index to set.
* @return This Buf.
*/
T writerIndex(int index);
}

View File

@ -102,7 +102,7 @@ public class BBufAccessBenchmark extends AbstractMicrobenchmark {
@Benchmark
public int readBatch() {
buffer.readerIndex(0).touch();
buffer.readerIndex(0);
int result = 0;
// WARNING!
// Please do not replace this sum loop with a BlackHole::consume loop: