CompositeByteBuf tidy-up (#8784)

Motivation

There's some miscellaneous cleanup/simplification of CompositeByteBuf
which would help make the code a bit clearer.

Modifications

- Simplify web of constructors and addComponents methods, reducing
duplication of logic
- Rename `Component.freeIfNecessary()` method to just `free()`, which is
less confusing (see #8641)
- Make loop in addComponents0(...) method more verbose/readable (see
https://github.com/netty/netty/pull/8437#discussion_r232124414)
- Simplify addition/subtraction in setBytes(...) methods

Result

Smaller/clearer code
This commit is contained in:
Nick Hill 2019-02-01 01:31:53 -08:00 committed by Norman Maurer
parent 7bba4f49cf
commit 98aa5fbd66

View File

@ -96,8 +96,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
this(alloc, direct, maxNumComponents, this(alloc, direct, maxNumComponents,
buffers instanceof Collection ? ((Collection<ByteBuf>) buffers).size() : 0); buffers instanceof Collection ? ((Collection<ByteBuf>) buffers).size() : 0);
addComponents0(false, 0, buffers); addComponents(false, 0, buffers);
consolidateIfNeeded();
setIndex(0, capacity()); setIndex(0, capacity());
} }
@ -220,10 +219,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
* {@link CompositeByteBuf}. * {@link CompositeByteBuf}.
*/ */
public CompositeByteBuf addComponent(boolean increaseWriterIndex, ByteBuf buffer) { public CompositeByteBuf addComponent(boolean increaseWriterIndex, ByteBuf buffer) {
checkNotNull(buffer, "buffer"); return addComponent(increaseWriterIndex, componentCount, buffer);
addComponent0(increaseWriterIndex, componentCount, buffer);
consolidateIfNeeded();
return this;
} }
/** /**
@ -252,9 +248,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
* ownership of all {@link ByteBuf} objects is transferred to this {@link CompositeByteBuf}. * ownership of all {@link ByteBuf} objects is transferred to this {@link CompositeByteBuf}.
*/ */
public CompositeByteBuf addComponents(boolean increaseWriterIndex, Iterable<ByteBuf> buffers) { public CompositeByteBuf addComponents(boolean increaseWriterIndex, Iterable<ByteBuf> buffers) {
addComponents0(increaseWriterIndex, componentCount, buffers); return addComponents(increaseWriterIndex, componentCount, buffers);
consolidateIfNeeded();
return this;
} }
/** /**
@ -304,7 +298,6 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
} }
} }
// unwrap if already sliced
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private Component newComponent(ByteBuf buf, int offset) { private Component newComponent(ByteBuf buf, int offset) {
if (checkAccessible && buf.refCnt() == 0) { if (checkAccessible && buf.refCnt() == 0) {
@ -312,6 +305,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
} }
int srcIndex = buf.readerIndex(), len = buf.readableBytes(); int srcIndex = buf.readerIndex(), len = buf.readableBytes();
ByteBuf slice = null; ByteBuf slice = null;
// unwrap if already sliced
if (buf instanceof AbstractUnpooledSlicedByteBuf) { if (buf instanceof AbstractUnpooledSlicedByteBuf) {
srcIndex += ((AbstractUnpooledSlicedByteBuf) buf).idx(0); srcIndex += ((AbstractUnpooledSlicedByteBuf) buf).idx(0);
slice = buf; slice = buf;
@ -345,20 +339,25 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
return this; return this;
} }
private int addComponents0(boolean increaseWriterIndex, final int cIndex, ByteBuf[] buffers, int arrOffset) { private CompositeByteBuf addComponents0(boolean increaseWriterIndex,
final int cIndex, ByteBuf[] buffers, int arrOffset) {
final int len = buffers.length, count = len - arrOffset; final int len = buffers.length, count = len - arrOffset;
// only set ci after we've shifted so that finally block logic is always correct
int ci = Integer.MAX_VALUE; int ci = Integer.MAX_VALUE;
try { try {
checkComponentIndex(cIndex); checkComponentIndex(cIndex);
shiftComps(cIndex, count); // will increase componentCount shiftComps(cIndex, count); // will increase componentCount
ci = cIndex; // only set this after we've shifted so that finally block logic is always correct
int nextOffset = cIndex > 0 ? components[cIndex - 1].endOffset : 0; int nextOffset = cIndex > 0 ? components[cIndex - 1].endOffset : 0;
for (ByteBuf b; arrOffset < len && (b = buffers[arrOffset]) != null; arrOffset++, ci++) { for (ci = cIndex; arrOffset < len; arrOffset++, ci++) {
ByteBuf b = buffers[arrOffset];
if (b == null) {
break;
}
Component c = newComponent(b, nextOffset); Component c = newComponent(b, nextOffset);
components[ci] = c; components[ci] = c;
nextOffset = c.endOffset; nextOffset = c.endOffset;
} }
return ci; return this;
} finally { } finally {
// ci is now the index following the last successfully added component // ci is now the index following the last successfully added component
if (ci < componentCount) { if (ci < componentCount) {
@ -379,7 +378,6 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
private <T> int addComponents0(boolean increaseWriterIndex, int cIndex, private <T> int addComponents0(boolean increaseWriterIndex, int cIndex,
ByteWrapper<T> wrapper, T[] buffers, int offset) { ByteWrapper<T> wrapper, T[] buffers, int offset) {
checkNotNull(buffers, "buffers");
checkComponentIndex(cIndex); checkComponentIndex(cIndex);
// No need for consolidation // No need for consolidation
@ -413,18 +411,16 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
* {@link CompositeByteBuf}. * {@link CompositeByteBuf}.
*/ */
public CompositeByteBuf addComponents(int cIndex, Iterable<ByteBuf> buffers) { public CompositeByteBuf addComponents(int cIndex, Iterable<ByteBuf> buffers) {
addComponents0(false, cIndex, buffers); return addComponents(false, cIndex, buffers);
consolidateIfNeeded();
return this;
} }
// TODO optimize further, similar to ByteBuf[] version // TODO optimize further, similar to ByteBuf[] version
// (difference here is that we don't know *always* know precise size increase in advance, // (difference here is that we don't know *always* know precise size increase in advance,
// but we do in the most common case that the Iterable is a Collection) // but we do in the most common case that the Iterable is a Collection)
private int addComponents0(boolean increaseIndex, int cIndex, Iterable<ByteBuf> buffers) { private CompositeByteBuf addComponents(boolean increaseIndex, int cIndex, Iterable<ByteBuf> buffers) {
if (buffers instanceof ByteBuf) { if (buffers instanceof ByteBuf) {
// If buffers also implements ByteBuf (e.g. CompositeByteBuf), it has to go to addComponent(ByteBuf). // If buffers also implements ByteBuf (e.g. CompositeByteBuf), it has to go to addComponent(ByteBuf).
return addComponent0(increaseIndex, cIndex, (ByteBuf) buffers); return addComponent(increaseIndex, cIndex, (ByteBuf) buffers);
} }
checkNotNull(buffers, "buffers"); checkNotNull(buffers, "buffers");
Iterator<ByteBuf> it = buffers.iterator(); Iterator<ByteBuf> it = buffers.iterator();
@ -440,12 +436,13 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
cIndex = addComponent0(increaseIndex, cIndex, b) + 1; cIndex = addComponent0(increaseIndex, cIndex, b) + 1;
cIndex = Math.min(cIndex, componentCount); cIndex = Math.min(cIndex, componentCount);
} }
return cIndex;
} finally { } finally {
while (it.hasNext()) { while (it.hasNext()) {
ReferenceCountUtil.safeRelease(it.next()); ReferenceCountUtil.safeRelease(it.next());
} }
} }
consolidateIfNeeded();
return this;
} }
/** /**
@ -516,7 +513,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
if (lastAccessed == comp) { if (lastAccessed == comp) {
lastAccessed = null; lastAccessed = null;
} }
comp.freeIfNecessary(); comp.free();
removeComp(cIndex); removeComp(cIndex);
if (comp.length() > 0) { if (comp.length() > 0) {
// Only need to call updateComponentOffsets if the length was > 0 // Only need to call updateComponentOffsets if the length was > 0
@ -547,7 +544,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
if (lastAccessed == c) { if (lastAccessed == c) {
lastAccessed = null; lastAccessed = null;
} }
c.freeIfNecessary(); c.free();
} }
removeCompRange(cIndex, endIndex); removeCompRange(cIndex, endIndex);
@ -759,7 +756,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
c.slice = null; c.slice = null;
break; break;
} }
c.freeIfNecessary(); c.free();
bytesToTrim -= cLength; bytesToTrim -= cLength;
} }
removeCompRange(i + 1, size); removeCompRange(i + 1, size);
@ -1305,15 +1302,11 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
} }
} }
index += localReadBytes;
length -= localReadBytes;
readBytes += localReadBytes;
if (localReadBytes == localLength) { if (localReadBytes == localLength) {
index += localLength;
length -= localLength;
readBytes += localLength;
i ++; i ++;
} else {
index += localReadBytes;
length -= localReadBytes;
readBytes += localReadBytes;
} }
} while (length > 0); } while (length > 0);
@ -1351,15 +1344,11 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
} }
} }
index += localReadBytes;
length -= localReadBytes;
readBytes += localReadBytes;
if (localReadBytes == localLength) { if (localReadBytes == localLength) {
index += localLength;
length -= localLength;
readBytes += localLength;
i ++; i ++;
} else {
index += localReadBytes;
length -= localReadBytes;
readBytes += localReadBytes;
} }
} while (length > 0); } while (length > 0);
@ -1397,15 +1386,11 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
} }
} }
index += localReadBytes;
length -= localReadBytes;
readBytes += localReadBytes;
if (localReadBytes == localLength) { if (localReadBytes == localLength) {
index += localLength;
length -= localLength;
readBytes += localLength;
i ++; i ++;
} else {
index += localReadBytes;
length -= localReadBytes;
readBytes += localReadBytes;
} }
} while (length > 0); } while (length > 0);
@ -1677,7 +1662,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
int writerIndex = writerIndex(); int writerIndex = writerIndex();
if (readerIndex == writerIndex && writerIndex == capacity()) { if (readerIndex == writerIndex && writerIndex == capacity()) {
for (int i = 0, size = componentCount; i < size; i++) { for (int i = 0, size = componentCount; i < size; i++) {
components[i].freeIfNecessary(); components[i].free();
} }
lastAccessed = null; lastAccessed = null;
clearComps(); clearComps();
@ -1689,7 +1674,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
// Remove read components. // Remove read components.
int firstComponentId = toComponentIndex0(readerIndex); int firstComponentId = toComponentIndex0(readerIndex);
for (int i = 0; i < firstComponentId; i ++) { for (int i = 0; i < firstComponentId; i ++) {
components[i].freeIfNecessary(); components[i].free();
} }
lastAccessed = null; lastAccessed = null;
removeCompRange(0, firstComponentId); removeCompRange(0, firstComponentId);
@ -1715,7 +1700,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
int writerIndex = writerIndex(); int writerIndex = writerIndex();
if (readerIndex == writerIndex && writerIndex == capacity()) { if (readerIndex == writerIndex && writerIndex == capacity()) {
for (int i = 0, size = componentCount; i < size; i++) { for (int i = 0, size = componentCount; i < size; i++) {
components[i].freeIfNecessary(); components[i].free();
} }
lastAccessed = null; lastAccessed = null;
clearComps(); clearComps();
@ -1728,7 +1713,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
int firstComponentId = toComponentIndex0(readerIndex); int firstComponentId = toComponentIndex0(readerIndex);
for (int i = 0; i < firstComponentId; i ++) { for (int i = 0; i < firstComponentId; i ++) {
Component c = components[i]; Component c = components[i];
c.freeIfNecessary(); c.free();
if (lastAccessed == c) { if (lastAccessed == c) {
lastAccessed = null; lastAccessed = null;
} }
@ -1738,7 +1723,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
Component c = components[firstComponentId]; Component c = components[firstComponentId];
if (readerIndex == c.endOffset) { if (readerIndex == c.endOffset) {
// new slice would be empty, so remove instead // new slice would be empty, so remove instead
c.freeIfNecessary(); c.free();
if (lastAccessed == c) { if (lastAccessed == c) {
lastAccessed = null; lastAccessed = null;
} }
@ -1804,7 +1789,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
// copy then release // copy then release
void transferTo(ByteBuf dst) { void transferTo(ByteBuf dst) {
dst.writeBytes(buf, idx(offset), length()); dst.writeBytes(buf, idx(offset), length());
freeIfNecessary(); free();
} }
ByteBuf slice() { ByteBuf slice() {
@ -1815,7 +1800,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
return buf.duplicate().setIndex(idx(offset), idx(endOffset)); return buf.duplicate().setIndex(idx(offset), idx(endOffset));
} }
void freeIfNecessary() { void free() {
// Release the slice if present since it may have a different // Release the slice if present since it may have a different
// refcount to the unwrapped buf if it is a PooledSlicedByteBuf // refcount to the unwrapped buf if it is a PooledSlicedByteBuf
ByteBuf buffer = slice; ByteBuf buffer = slice;
@ -1824,7 +1809,8 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
} else { } else {
buf.release(); buf.release();
} }
// null out in either case since it could be racy // null out in either case since it could be racy if set lazily (but not
// in the case we care about, where it will have been set in the ctor)
slice = null; slice = null;
} }
} }
@ -2130,7 +2116,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
// We're not using foreach to avoid creating an iterator. // We're not using foreach to avoid creating an iterator.
// see https://github.com/netty/netty/issues/2642 // see https://github.com/netty/netty/issues/2642
for (int i = 0, size = componentCount; i < size; i++) { for (int i = 0, size = componentCount; i < size; i++) {
components[i].freeIfNecessary(); components[i].free();
} }
} }