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 @Setter
private Protocol protocol; private Protocol protocol;
private boolean server; private final boolean server;
@Setter @Setter
private int protocolVersion; 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 protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception
{ {
Protocol.DirectionData prot = ( server ) ? protocol.TO_SERVER : protocol.TO_CLIENT; Protocol.DirectionData prot = ( server ) ? protocol.TO_SERVER : protocol.TO_CLIENT;
ByteBuf copy = in.copy(); // TODO ByteBuf slice = in.slice().retain();
try try
{ {
int packetId = DefinedPacket.readVarInt( in ); int packetId = DefinedPacket.readVarInt( in );
DefinedPacket packet = null; DefinedPacket packet = prot.createPacket( packetId );
if ( prot.hasPacket( packetId ) ) if ( packet != null )
{ {
packet = prot.createPacket( packetId );
packet.read( in, prot.getDirection(), protocolVersion ); 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 ); 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() ); in.skipBytes( in.readableBytes() );
} }
out.add( new PacketWrapper( packet, copy ) ); out.add( new PacketWrapper( packet, slice ) );
copy = null; slice = null;
} finally } 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 Class<? extends DefinedPacket>[] packetClasses = new Class[ MAX_PACKET_ID ];
private final Constructor<? extends DefinedPacket>[] packetConstructors = new Constructor[ 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) public final DefinedPacket createPacket(int id)
{ {
if ( id > MAX_PACKET_ID ) if ( id > MAX_PACKET_ID )
{ {
throw new BadPacketException( "Packet with id " + id + " outside of range " ); 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 try
{ {
return packetConstructors[id].newInstance(); return ( constructor == null ) ? null : constructor.newInstance();
} catch ( ReflectiveOperationException ex ) } catch ( ReflectiveOperationException ex )
{ {
throw new BadPacketException( "Could not construct packet with id " + id, ex ); throw new BadPacketException( "Could not construct packet with id " + id, ex );

View File

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

View File

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