Skip to content

Commit 9e9bde5

Browse files
committed
Use IntObjectMap for EncapsulatedPacket instead of array
Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com>
1 parent 6157d88 commit 9e9bde5

File tree

1 file changed

+38
-25
lines changed

1 file changed

+38
-25
lines changed

transport-raknet/src/main/java/org/cloudburstmc/netty/util/SplitPacketHelper.java

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,57 +22,69 @@
2222
import io.netty.util.IllegalReferenceCountException;
2323
import io.netty.util.ReferenceCountUtil;
2424
import io.netty.util.ReferenceCounted;
25+
import io.netty.util.collection.IntObjectHashMap;
26+
import io.netty.util.collection.IntObjectMap;
2527
import org.cloudburstmc.netty.channel.raknet.packet.EncapsulatedPacket;
2628

2729
import java.util.Objects;
2830

2931
public class SplitPacketHelper extends AbstractReferenceCounted {
30-
private final EncapsulatedPacket[] packets;
32+
private final IntObjectMap<EncapsulatedPacket> packets;
33+
private final int expectedLength;
3134
private final long created = System.currentTimeMillis();
3235

3336
public SplitPacketHelper(long expectedLength) {
3437
if (expectedLength < 2) {
3538
throw new IllegalArgumentException("expectedLength must be greater than 1");
3639
}
37-
if (expectedLength > 8192) {
38-
throw new IllegalArgumentException("Too many split parts, expectedLength must be less than 8192");
40+
41+
if (expectedLength > Integer.MAX_VALUE) {
42+
throw new IllegalArgumentException("expectedLength must be <= Integer.MAX_VALUE");
3943
}
40-
this.packets = new EncapsulatedPacket[(int) expectedLength];
44+
45+
this.expectedLength = (int) expectedLength;
46+
this.packets = new IntObjectHashMap<>();
4147
}
4248

43-
public EncapsulatedPacket add(EncapsulatedPacket packet, ByteBufAllocator alloc) {
49+
public EncapsulatedPacket add(EncapsulatedPacket packet, ByteBufAllocator alloc) {
4450
Objects.requireNonNull(packet, "packet cannot be null");
4551
if (!packet.isSplit()) throw new IllegalArgumentException("Packet is not split");
4652
if (this.refCnt() <= 0) throw new IllegalReferenceCountException(this.refCnt());
47-
if (packet.getPartIndex() < 0 || packet.getPartIndex() >= this.packets.length) {
53+
54+
int partIndex = packet.getPartIndex();
55+
if (partIndex < 0 || partIndex >= this.expectedLength) {
4856
throw new IllegalArgumentException(String.format("Split packet part index out of range. Got %s, expected 0-%s",
49-
packet.getPartIndex(), this.packets.length - 1));
57+
partIndex, this.expectedLength - 1));
5058
}
5159

52-
int partIndex = packet.getPartIndex();
53-
if (this.packets[partIndex] != null) {
54-
// Duplicate
60+
if (this.packets.containsKey(partIndex)) {
5561
return null;
5662
}
63+
5764
// Retain the packet so it can be reassembled later.
58-
this.packets[partIndex] = packet.retain();
65+
this.packets.put(partIndex, packet.retain());
5966

60-
int sz = 0;
61-
for (EncapsulatedPacket netPacket : this.packets) {
62-
if (netPacket == null) {
63-
return null;
67+
if (this.packets.size() == this.expectedLength) {
68+
int sz = 0;
69+
// Iterate by index to ensure we sum sizes and write bytes in the correct order
70+
for (int i = 0; i < this.expectedLength; i++) {
71+
EncapsulatedPacket netPacket = this.packets.get(i);
72+
// netPacket should not be null here if size() == expectedLength and indices are verified
73+
sz += netPacket.getBuffer().readableBytes();
74+
}
75+
76+
// We can't use a composite buffer as the native code will choke on it
77+
ByteBuf reassembled = alloc.ioBuffer(sz);
78+
for (int i = 0; i < this.expectedLength; i++) {
79+
EncapsulatedPacket netPacket = this.packets.get(i);
80+
ByteBuf buf = netPacket.getBuffer();
81+
reassembled.writeBytes(buf, buf.readerIndex(), buf.readableBytes());
6482
}
65-
sz += netPacket.getBuffer().readableBytes();
66-
}
6783

68-
// We can't use a composite buffer as the native code will choke on it
69-
ByteBuf reassembled = alloc.ioBuffer(sz);
70-
for (EncapsulatedPacket netPacket : this.packets) {
71-
ByteBuf buf = netPacket.getBuffer();
72-
reassembled.writeBytes(buf, buf.readerIndex(), buf.readableBytes());
84+
return packet.fromSplit(reassembled);
7385
}
7486

75-
return packet.fromSplit(reassembled);
87+
return null;
7688
}
7789

7890
public boolean expired() {
@@ -82,11 +94,12 @@ public boolean expired() {
8294
return System.currentTimeMillis() - created >= 30000;
8395
}
8496

85-
@Override
97+
@Override
8698
protected void deallocate() {
87-
for (EncapsulatedPacket packet : this.packets) {
99+
for (EncapsulatedPacket packet : this.packets.values()) {
88100
ReferenceCountUtil.release(packet);
89101
}
102+
this.packets.clear();
90103
}
91104

92105
@Override

0 commit comments

Comments
 (0)