Add optimized version of setZero(...) / writeZero(...) for Unsafe*ByteBuf implementations

Motivation:

Unsafe offers a method to set memory to a specific value. This can be used to implement an optimized version of setZero(...) and writeZero(...)

Modifications:

Add implementation for all Unsafe*ByteBuf implementations.

Result:

Faster setZero(...) and writeZero(...)
This commit is contained in:
Norman Maurer 2016-05-23 14:53:31 +02:00
parent 339b512e70
commit db6b72da19
7 changed files with 119 additions and 0 deletions

View File

@ -371,4 +371,19 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
} }
return super.newSwappedByteBuf(); return super.newSwappedByteBuf();
} }
@Override
public ByteBuf setZero(int index, int length) {
UnsafeByteBufUtil.setZero(this, addr(index), index, length);
return this;
}
@Override
public ByteBuf writeZero(int length) {
ensureWritable(length);
int wIndex = writerIndex;
setZero(wIndex, length);
writerIndex = wIndex + length;
return this;
}
} }

View File

@ -128,6 +128,34 @@ final class PooledUnsafeHeapByteBuf extends PooledHeapByteBuf {
UnsafeByteBufUtil.setLongLE(memory, idx(index), value); UnsafeByteBufUtil.setLongLE(memory, idx(index), value);
} }
@Override
public ByteBuf setZero(int index, int length) {
if (PlatformDependent.javaVersion() >= 7) {
// Only do on java7+ as the needed Unsafe call was only added there.
_setZero(index, length);
return this;
}
return super.setZero(index, length);
}
@Override
public ByteBuf writeZero(int length) {
if (PlatformDependent.javaVersion() >= 7) {
// Only do on java7+ as the needed Unsafe call was only added there.
ensureWritable(length);
int wIndex = writerIndex;
_setZero(wIndex, length);
writerIndex = wIndex + length;
return this;
}
return super.writeZero(length);
}
private void _setZero(int index, int length) {
checkIndex(index, length);
UnsafeByteBufUtil.setZero(memory, idx(index), length);
}
@Override @Override
@Deprecated @Deprecated
protected SwappedByteBuf newSwappedByteBuf() { protected SwappedByteBuf newSwappedByteBuf() {

View File

@ -503,4 +503,19 @@ public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf
} }
return super.newSwappedByteBuf(); return super.newSwappedByteBuf();
} }
@Override
public ByteBuf setZero(int index, int length) {
UnsafeByteBufUtil.setZero(this, addr(index), index, length);
return this;
}
@Override
public ByteBuf writeZero(int length) {
ensureWritable(length);
int wIndex = writerIndex;
setZero(wIndex, length);
writerIndex = wIndex + length;
return this;
}
} }

View File

@ -236,6 +236,34 @@ final class UnpooledUnsafeHeapByteBuf extends UnpooledHeapByteBuf {
UnsafeByteBufUtil.setLongLE(array, index, value); UnsafeByteBufUtil.setLongLE(array, index, value);
} }
@Override
public ByteBuf setZero(int index, int length) {
if (PlatformDependent.javaVersion() >= 7) {
// Only do on java7+ as the needed Unsafe call was only added there.
_setZero(index, length);
return this;
}
return super.setZero(index, length);
}
@Override
public ByteBuf writeZero(int length) {
if (PlatformDependent.javaVersion() >= 7) {
// Only do on java7+ as the needed Unsafe call was only added there.
ensureWritable(length);
int wIndex = writerIndex;
_setZero(wIndex, length);
writerIndex = wIndex + length;
return this;
}
return super.writeZero(length);
}
private void _setZero(int index, int length) {
checkIndex(index, length);
UnsafeByteBufUtil.setZero(array, index, length);
}
@Override @Override
@Deprecated @Deprecated
protected SwappedByteBuf newSwappedByteBuf() { protected SwappedByteBuf newSwappedByteBuf() {

View File

@ -33,6 +33,7 @@ import static io.netty.util.internal.PlatformDependent.BIG_ENDIAN_NATIVE_ORDER;
*/ */
final class UnsafeByteBufUtil { final class UnsafeByteBufUtil {
private static final boolean UNALIGNED = PlatformDependent.isUnaligned(); private static final boolean UNALIGNED = PlatformDependent.isUnaligned();
private static final byte ZERO = 0;
static byte getByte(long address) { static byte getByte(long address) {
return PlatformDependent.getByte(address); return PlatformDependent.getByte(address);
@ -451,6 +452,13 @@ final class UnsafeByteBufUtil {
} }
} }
static void setZero(byte[] array, int index, int length) {
if (length == 0) {
return;
}
PlatformDependent.setMemory(array, index, length, ZERO);
}
static ByteBuf copy(AbstractByteBuf buf, long addr, int index, int length) { static ByteBuf copy(AbstractByteBuf buf, long addr, int index, int length) {
buf.checkIndex(index, length); buf.checkIndex(index, length);
ByteBuf copy = buf.alloc().directBuffer(length, buf.maxCapacity()); ByteBuf copy = buf.alloc().directBuffer(length, buf.maxCapacity());
@ -602,5 +610,14 @@ final class UnsafeByteBufUtil {
} }
} }
static void setZero(AbstractByteBuf buf, long addr, int index, int length) {
if (length == 0) {
return;
}
buf.checkIndex(index, length);
PlatformDependent.setMemory(addr, length, ZERO);
}
private UnsafeByteBufUtil() { } private UnsafeByteBufUtil() { }
} }

View File

@ -496,6 +496,14 @@ public final class PlatformDependent {
PlatformDependent0.copyMemory(null, srcAddr, dst, BYTE_ARRAY_BASE_OFFSET + dstIndex, length); PlatformDependent0.copyMemory(null, srcAddr, dst, BYTE_ARRAY_BASE_OFFSET + dstIndex, length);
} }
public static void setMemory(byte[] dst, int dstIndex, long bytes, byte value) {
PlatformDependent0.setMemory(dst, BYTE_ARRAY_BASE_OFFSET + dstIndex, bytes, value);
}
public static void setMemory(long address, long bytes, byte value) {
PlatformDependent0.setMemory(address, bytes, value);
}
/** /**
* Compare two {@code byte} arrays for equality. For performance reasons no bounds checking on the * Compare two {@code byte} arrays for equality. For performance reasons no bounds checking on the
* parameters is performed. * parameters is performed.

View File

@ -322,6 +322,14 @@ final class PlatformDependent0 {
} }
} }
static void setMemory(long address, long bytes, byte value) {
UNSAFE.setMemory(address, bytes, value);
}
static void setMemory(Object o, long offset, long bytes, byte value) {
UNSAFE.setMemory(o, offset, bytes, value);
}
static boolean equals(byte[] bytes1, int startPos1, byte[] bytes2, int startPos2, int length) { static boolean equals(byte[] bytes1, int startPos1, byte[] bytes2, int startPos2, int length) {
if (length == 0) { if (length == 0) {
return true; return true;