In (Pooled|Unpooled)UnsafeDirectByteBuf copy memory directly to and from ByteBuffer
Motivation: When moving bytes between a PooledUnsafeDirectByteBuf or an UnpooledUnsafeDirectByteBuf and a ByteBuffer, a temp ByteBuffer is allocated and will need to be GCed. This is a common case since a ByteBuffer is always needed when reading/writing on a file, for example. Modifications: Use PlatformDependent.copyMemory() to avoid the need for the temp ByteBuffer Result: No temp ByteBuffer allocated and GCed.
This commit is contained in:
parent
3bc4d2330a
commit
a6324758b8
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package io.netty.buffer;
|
package io.netty.buffer;
|
||||||
|
|
||||||
import io.netty.buffer.PooledByteBufAllocator.PoolThreadLocalCache;
|
|
||||||
import io.netty.util.Recycler;
|
import io.netty.util.Recycler;
|
||||||
import io.netty.util.internal.PlatformDependent;
|
import io.netty.util.internal.PlatformDependent;
|
||||||
|
|
||||||
@ -149,29 +148,30 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf getBytes(int index, ByteBuffer dst) {
|
public ByteBuf getBytes(int index, ByteBuffer dst) {
|
||||||
getBytes(index, dst, false);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getBytes(int index, ByteBuffer dst, boolean internal) {
|
|
||||||
checkIndex(index);
|
checkIndex(index);
|
||||||
int bytesToCopy = Math.min(capacity() - index, dst.remaining());
|
int bytesToCopy = Math.min(capacity() - index, dst.remaining());
|
||||||
ByteBuffer tmpBuf;
|
if (bytesToCopy == 0) {
|
||||||
if (internal) {
|
return this;
|
||||||
tmpBuf = internalNioBuffer();
|
|
||||||
} else {
|
|
||||||
tmpBuf = memory.duplicate();
|
|
||||||
}
|
}
|
||||||
index = idx(index);
|
|
||||||
tmpBuf.clear().position(index).limit(index + bytesToCopy);
|
if (dst.isDirect()) {
|
||||||
dst.put(tmpBuf);
|
// Copy to direct memory
|
||||||
|
long dstAddress = PlatformDependent.directBufferAddress(dst);
|
||||||
|
PlatformDependent.copyMemory(addr(index), dstAddress + dst.position(), bytesToCopy);
|
||||||
|
} else {
|
||||||
|
// Copy to array
|
||||||
|
PlatformDependent.copyMemory(addr(index), dst.array(), dst.arrayOffset() + dst.position(), bytesToCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
dst.position(dst.position() + bytesToCopy);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf readBytes(ByteBuffer dst) {
|
public ByteBuf readBytes(ByteBuffer dst) {
|
||||||
int length = dst.remaining();
|
int length = dst.remaining();
|
||||||
checkReadableBytes(length);
|
checkReadableBytes(length);
|
||||||
getBytes(readerIndex, dst, true);
|
getBytes(readerIndex, dst);
|
||||||
readerIndex += length;
|
readerIndex += length;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -280,14 +280,21 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
|
|||||||
@Override
|
@Override
|
||||||
public ByteBuf setBytes(int index, ByteBuffer src) {
|
public ByteBuf setBytes(int index, ByteBuffer src) {
|
||||||
checkIndex(index, src.remaining());
|
checkIndex(index, src.remaining());
|
||||||
ByteBuffer tmpBuf = internalNioBuffer();
|
|
||||||
if (src == tmpBuf) {
|
int length = src.remaining();
|
||||||
src = src.duplicate();
|
if (length == 0) {
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
index = idx(index);
|
if (src.isDirect()) {
|
||||||
tmpBuf.clear().position(index).limit(index + src.remaining());
|
// Copy from direct memory
|
||||||
tmpBuf.put(src);
|
long srcAddress = PlatformDependent.directBufferAddress(src);
|
||||||
|
PlatformDependent.copyMemory(srcAddress + src.position(), addr(index), src.remaining());
|
||||||
|
} else {
|
||||||
|
// Copy from array
|
||||||
|
PlatformDependent.copyMemory(src.array(), src.arrayOffset() + src.position(), addr(index), length);
|
||||||
|
}
|
||||||
|
src.position(src.position() + length);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,32 +285,34 @@ public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf getBytes(int index, ByteBuffer dst) {
|
public ByteBuf getBytes(int index, ByteBuffer dst) {
|
||||||
getBytes(index, dst, false);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getBytes(int index, ByteBuffer dst, boolean internal) {
|
|
||||||
checkIndex(index);
|
checkIndex(index);
|
||||||
if (dst == null) {
|
if (dst == null) {
|
||||||
throw new NullPointerException("dst");
|
throw new NullPointerException("dst");
|
||||||
}
|
}
|
||||||
|
|
||||||
int bytesToCopy = Math.min(capacity() - index, dst.remaining());
|
int bytesToCopy = Math.min(capacity() - index, dst.remaining());
|
||||||
ByteBuffer tmpBuf;
|
if (bytesToCopy == 0) {
|
||||||
if (internal) {
|
return this;
|
||||||
tmpBuf = internalNioBuffer();
|
|
||||||
} else {
|
|
||||||
tmpBuf = buffer.duplicate();
|
|
||||||
}
|
}
|
||||||
tmpBuf.clear().position(index).limit(index + bytesToCopy);
|
|
||||||
dst.put(tmpBuf);
|
if (dst.isDirect()) {
|
||||||
|
// Copy to direct memory
|
||||||
|
long dstAddress = PlatformDependent.directBufferAddress(dst);
|
||||||
|
PlatformDependent.copyMemory(addr(index), dstAddress + dst.position(), bytesToCopy);
|
||||||
|
} else {
|
||||||
|
// Copy to array
|
||||||
|
PlatformDependent.copyMemory(addr(index), dst.array(), dst.arrayOffset() + dst.position(), bytesToCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
dst.position(dst.position() + bytesToCopy);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuf readBytes(ByteBuffer dst) {
|
public ByteBuf readBytes(ByteBuffer dst) {
|
||||||
int length = dst.remaining();
|
int length = dst.remaining();
|
||||||
checkReadableBytes(length);
|
checkReadableBytes(length);
|
||||||
getBytes(readerIndex, dst, true);
|
getBytes(readerIndex, dst);
|
||||||
readerIndex += length;
|
readerIndex += length;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -377,13 +379,20 @@ public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf
|
|||||||
@Override
|
@Override
|
||||||
public ByteBuf setBytes(int index, ByteBuffer src) {
|
public ByteBuf setBytes(int index, ByteBuffer src) {
|
||||||
ensureAccessible();
|
ensureAccessible();
|
||||||
ByteBuffer tmpBuf = internalNioBuffer();
|
int length = src.remaining();
|
||||||
if (src == tmpBuf) {
|
if (length == 0) {
|
||||||
src = src.duplicate();
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpBuf.clear().position(index).limit(index + src.remaining());
|
if (src.isDirect()) {
|
||||||
tmpBuf.put(src);
|
// Copy from direct memory
|
||||||
|
long srcAddress = PlatformDependent.directBufferAddress(src);
|
||||||
|
PlatformDependent.copyMemory(srcAddress + src.position(), addr(index), src.remaining());
|
||||||
|
} else {
|
||||||
|
// Copy from array
|
||||||
|
PlatformDependent.copyMemory(src.array(), src.arrayOffset() + src.position(), addr(index), length);
|
||||||
|
}
|
||||||
|
src.position(src.position() + length);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user