Reduce amount of memcpy within proxy pipeline.

This commit is contained in:
md_5 2016-01-24 11:22:39 +11:00
parent 79dbdea107
commit 052131c1fa
4 changed files with 34 additions and 37 deletions

View File

@ -13,7 +13,7 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf>
@Setter
private Protocol protocol;
private boolean server;
private final boolean server;
@Setter
private int protocolVersion;
@ -21,18 +21,18 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf>
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception
{
Protocol.DirectionData prot = ( server ) ? protocol.TO_SERVER : protocol.TO_CLIENT;
ByteBuf copy = in.copy(); // TODO
ByteBuf slice = in.slice().retain();
try
{
int packetId = DefinedPacket.readVarInt( in );
DefinedPacket packet = null;
if ( prot.hasPacket( packetId ) )
DefinedPacket packet = prot.createPacket( packetId );
if ( packet != null )
{
packet = prot.createPacket( packetId );
packet.read( in, prot.getDirection(), protocolVersion );
if ( in.readableBytes() != 0 )
if ( in.isReadable() )
{
throw new BadPacketException( "Did not read all bytes from packet " + packet.getClass() + " " + packetId + " Protocol " + protocol + " Direction " + prot );
}
@ -41,13 +41,13 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf>
in.skipBytes( in.readableBytes() );
}
out.add( new PacketWrapper( packet, copy ) );
copy = null;
out.add( new PacketWrapper( packet, slice ) );
slice = null;
} finally
{
if ( copy != null )
if ( slice != null )
{
copy.release();
slice.release();
}
}
}

View File

@ -120,25 +120,17 @@ public enum Protocol
private final Class<? extends DefinedPacket>[] packetClasses = new Class[ MAX_PACKET_ID ];
private final Constructor<? extends DefinedPacket>[] packetConstructors = new Constructor[ MAX_PACKET_ID ];
public boolean hasPacket(int id)
{
return id < MAX_PACKET_ID && packetConstructors[id] != null;
}
public final DefinedPacket createPacket(int id)
{
if ( id > MAX_PACKET_ID )
{
throw new BadPacketException( "Packet with id " + id + " outside of range " );
}
if ( packetConstructors[id] == null )
{
throw new BadPacketException( "No packet with id " + id );
}
Constructor<? extends DefinedPacket> constructor = packetConstructors[id];
try
{
return packetConstructors[id].newInstance();
return ( constructor == null ) ? null : constructor.newInstance();
} catch ( ReflectiveOperationException ex )
{
throw new BadPacketException( "Could not construct packet with id " + id, ex );

View File

@ -40,11 +40,8 @@ public class Varint21FrameDecoder extends ByteToMessageDecoder
return;
} else
{
// TODO: Really should be a slice!
ByteBuf dst = ctx.alloc().directBuffer( length );
in.readBytes( dst );
out.add( dst );
out.add( in.slice( in.readerIndex(), length ).retain() );
in.skipBytes( length );
return;
}
}

View File

@ -1,13 +1,14 @@
package net.md_5.bungee.compress;
import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToMessageDecoder;
import java.util.List;
import net.md_5.bungee.jni.zlib.BungeeZlib;
import net.md_5.bungee.protocol.DefinedPacket;
public class PacketDecompressor extends ByteToMessageDecoder
public class PacketDecompressor extends MessageToMessageDecoder<ByteBuf>
{
private final BungeeZlib zlib = CompressFactory.zlib.newInstance();
@ -19,7 +20,7 @@ public class PacketDecompressor extends ByteToMessageDecoder
}
@Override
public void handlerRemoved0(ChannelHandlerContext ctx) throws Exception
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception
{
zlib.free();
}
@ -27,22 +28,29 @@ public class PacketDecompressor extends ByteToMessageDecoder
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception
{
if ( in.readableBytes() == 0 )
{
return;
}
int size = DefinedPacket.readVarInt( in );
if ( size == 0 )
{
out.add( in.copy() );
in.readerIndex( in.writerIndex() );
out.add( in.slice().retain() );
in.skipBytes( in.readableBytes() );
} else
{
ByteBuf decompressed = ctx.alloc().directBuffer();
zlib.process( in, decompressed );
out.add( decompressed );
try
{
zlib.process( in, decompressed );
Preconditions.checkState( decompressed.readableBytes() == size, "Decompressed packet size mismatch" );
out.add( decompressed );
decompressed = null;
} finally
{
if ( decompressed != null )
{
decompressed.release();
}
}
}
}
}