Skip to content
This repository was archived by the owner on Dec 12, 2022. It is now read-only.

Commit de305bd

Browse files
committed
Align slice sendability of composite buffers with that of non-composite buffers
This means we no longer need to have tests that are parameterised over non-sliced buffers.
1 parent d40989d commit de305bd

File tree

3 files changed

+61
-106
lines changed

3 files changed

+61
-106
lines changed

src/main/java/io/netty/buffer/api/CompositeBuffer.java

Lines changed: 30 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ public String toString() {
4848

4949
private final BufferAllocator allocator;
5050
private final TornBufferAccessors tornBufAccessors;
51-
private final boolean isSendable;
5251
private Buffer[] bufs;
5352
private int[] offsets; // The offset, for the composite buffer, where each constituent buffer starts.
5453
private int capacity;
@@ -60,7 +59,7 @@ public String toString() {
6059
private boolean readOnly;
6160

6261
CompositeBuffer(BufferAllocator allocator, Deref<Buffer>[] refs) {
63-
this(allocator, true, filterExternalBufs(refs), COMPOSITE_DROP, false);
62+
this(allocator, filterExternalBufs(refs), COMPOSITE_DROP, false);
6463
}
6564

6665
private static Buffer[] filterExternalBufs(Deref<Buffer>[] refs) {
@@ -114,11 +113,10 @@ private static Stream<Buffer> flattenBuffer(Buffer buf) {
114113
return Stream.of(buf);
115114
}
116115

117-
private CompositeBuffer(BufferAllocator allocator, boolean isSendable, Buffer[] bufs, Drop<CompositeBuffer> drop,
116+
private CompositeBuffer(BufferAllocator allocator, Buffer[] bufs, Drop<CompositeBuffer> drop,
118117
boolean acquireBufs) {
119118
super(drop);
120119
this.allocator = allocator;
121-
this.isSendable = isSendable;
122120
if (acquireBufs) {
123121
for (Buffer buf : bufs) {
124122
buf.acquire();
@@ -305,46 +303,31 @@ public Buffer slice(int offset, int length) {
305303
offset + ", and length was " + length + '.');
306304
}
307305
Buffer choice = (Buffer) chooseBuffer(offset, 0);
308-
Buffer[] slices = null;
309-
acquire(); // Increase reference count of the original composite buffer.
310-
Drop<CompositeBuffer> drop = obj -> {
311-
close(); // Decrement the reference count of the original composite buffer.
312-
COMPOSITE_DROP.drop(obj);
313-
};
314-
315-
try {
316-
if (length > 0) {
317-
slices = new Buffer[bufs.length];
318-
int off = subOffset;
319-
int cap = length;
320-
int i;
321-
for (i = searchOffsets(offset); cap > 0; i++) {
322-
var buf = bufs[i];
323-
int avail = buf.capacity() - off;
324-
slices[i] = buf.slice(off, Math.min(cap, avail));
325-
cap -= avail;
326-
off = 0;
327-
}
328-
slices = Arrays.copyOf(slices, i);
329-
} else {
330-
// Specialize for length == 0, since we must slice from at least one constituent buffer.
331-
slices = new Buffer[] { choice.slice(subOffset, 0) };
332-
}
333-
334-
return new CompositeBuffer(allocator, false, slices, drop, true);
335-
} catch (Throwable throwable) {
336-
// We called acquire prior to the try-clause. We need to undo that if we're not creating a composite buffer:
337-
close();
338-
throw throwable;
339-
} finally {
340-
if (slices != null) {
341-
for (Buffer slice : slices) {
342-
if (slice != null) {
343-
slice.close(); // Ownership now transfers to the composite buffer.
344-
}
345-
}
346-
}
306+
Buffer[] slices;
307+
308+
if (length > 0) {
309+
slices = new Buffer[bufs.length];
310+
int off = subOffset;
311+
int cap = length;
312+
int i;
313+
for (i = searchOffsets(offset); cap > 0; i++) {
314+
var buf = bufs[i];
315+
int avail = buf.capacity() - off;
316+
slices[i] = buf.slice(off, Math.min(cap, avail));
317+
cap -= avail;
318+
off = 0;
319+
}
320+
slices = Arrays.copyOf(slices, i);
321+
} else {
322+
// Specialize for length == 0, since we must slice from at least one constituent buffer.
323+
slices = new Buffer[] { choice.slice(subOffset, 0) };
347324
}
325+
326+
// Use the constructor that skips filtering out empty buffers, and skips acquiring on the buffers.
327+
// This is important because 1) slice() already acquired the buffers, and 2) if this slice is empty
328+
// then we need to keep holding on to it to prevent this originating composite buffer from getting
329+
// ownership. If it did, its behaviour would be inconsistent with that of a non-composite buffer.
330+
return new CompositeBuffer(allocator, slices, COMPOSITE_DROP, false);
348331
}
349332

350333
@Override
@@ -757,7 +740,7 @@ public Buffer bifurcate() {
757740
}
758741
if (bufs.length == 0) {
759742
// Bifurcating a zero-length buffer is trivial.
760-
return new CompositeBuffer(allocator, true, bufs, unsafeGetDrop(), true).order(order);
743+
return new CompositeBuffer(allocator, bufs, unsafeGetDrop(), true).order(order);
761744
}
762745

763746
int i = searchOffsets(woff);
@@ -769,7 +752,7 @@ public Buffer bifurcate() {
769752
}
770753
computeBufferOffsets();
771754
try {
772-
var compositeBuf = new CompositeBuffer(allocator, true, bifs, unsafeGetDrop(), true);
755+
var compositeBuf = new CompositeBuffer(allocator, bifs, unsafeGetDrop(), true);
773756
compositeBuf.order = order; // Preserve byte order even if bifs array is empty.
774757
return compositeBuf;
775758
} finally {
@@ -1172,7 +1155,7 @@ public CompositeBuffer transferOwnership(Drop<CompositeBuffer> drop) {
11721155
for (int i = 0; i < sends.length; i++) {
11731156
received[i] = sends[i].receive();
11741157
}
1175-
var composite = new CompositeBuffer(allocator, true, received, drop, true);
1158+
var composite = new CompositeBuffer(allocator, received, drop, true);
11761159
composite.readOnly = readOnly;
11771160
drop.attach(composite);
11781161
return composite;
@@ -1187,18 +1170,9 @@ void makeInaccessible() {
11871170
closed = true;
11881171
}
11891172

1190-
@Override
1191-
protected IllegalStateException notSendableException() {
1192-
if (!isSendable) {
1193-
return new IllegalStateException(
1194-
"Cannot send() this buffer. This buffer might be a slice of another buffer.");
1195-
}
1196-
return super.notSendableException();
1197-
}
1198-
11991173
@Override
12001174
public boolean isOwned() {
1201-
return isSendable && super.isOwned() && allConstituentsAreOwned();
1175+
return super.isOwned() && allConstituentsAreOwned();
12021176
}
12031177

12041178
private boolean allConstituentsAreOwned() {

src/main/java/io/netty/buffer/api/memseg/HeapMemorySegmentManager.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
*/
1616
package io.netty.buffer.api.memseg;
1717

18-
import io.netty.buffer.api.Buffer;
19-
import io.netty.buffer.api.Drop;
2018
import jdk.incubator.foreign.MemorySegment;
2119

2220
public class HeapMemorySegmentManager extends AbstractMemorySegmentManager {
@@ -29,15 +27,4 @@ public boolean isNative() {
2927
protected MemorySegment createSegment(long size) {
3028
return MemorySegment.ofArray(new byte[Math.toIntExact(size)]);
3129
}
32-
33-
@Override
34-
public Drop<Buffer> drop() {
35-
return convert(buf -> buf.makeInaccessible());
36-
}
37-
38-
@SuppressWarnings({ "unchecked", "UnnecessaryLocalVariable" })
39-
private static Drop<Buffer> convert(Drop<MemSegBuffer> drop) {
40-
Drop<?> tmp = drop;
41-
return (Drop<Buffer>) tmp;
42-
}
4330
}

0 commit comments

Comments
 (0)