From 3bf9a47fbf17bcaf62bed545ef1c8b7406ffe005 Mon Sep 17 00:00:00 2001 From: Andrew Steinborn Date: Fri, 20 Aug 2021 02:30:06 -0400 Subject: [PATCH] DensePacketRegistryMap's internal hash map should size based on a power of 2 --- .../packet/DensePacketRegistryMap.java | 9 +++-- .../velocitypowered/proxy/util/MathUtil.java | 39 +++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/util/MathUtil.java diff --git a/proxy/src/main/java/com/velocitypowered/proxy/network/registry/packet/DensePacketRegistryMap.java b/proxy/src/main/java/com/velocitypowered/proxy/network/registry/packet/DensePacketRegistryMap.java index bd8fe74e3..0cd220631 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/network/registry/packet/DensePacketRegistryMap.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/network/registry/packet/DensePacketRegistryMap.java @@ -17,6 +17,8 @@ package com.velocitypowered.proxy.network.registry.packet; +import static com.velocitypowered.proxy.util.MathUtil.nextHighestPowerOfTwo; + import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.network.ProtocolUtils; import com.velocitypowered.proxy.network.packet.Packet; @@ -41,11 +43,12 @@ public class DensePacketRegistryMap implements PacketRegistryMap { public DensePacketRegistryMap(Int2ObjectMap> mappings) { int size = mappings.keySet().stream().mapToInt(x -> x).max().orElse(0) + 1; + int hashTableSize = nextHighestPowerOfTwo(size); this.readersById = new PacketReader[size]; - this.writersByClass = new PacketWriter[size * 2]; - this.classesByKey = new Class[size * 2]; - this.idsByKey = new int[size * 2]; + this.writersByClass = new PacketWriter[hashTableSize]; + this.classesByKey = new Class[hashTableSize]; + this.idsByKey = new int[hashTableSize]; for (PacketMapping value : mappings.values()) { this.readersById[value.id] = value.reader; diff --git a/proxy/src/main/java/com/velocitypowered/proxy/util/MathUtil.java b/proxy/src/main/java/com/velocitypowered/proxy/util/MathUtil.java new file mode 100644 index 000000000..700bdf363 --- /dev/null +++ b/proxy/src/main/java/com/velocitypowered/proxy/util/MathUtil.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2018 Velocity Contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.velocitypowered.proxy.util; + +public class MathUtil { + + /** + * Rounds {@code v} to the next highest power of 2. + * + * @param v the number to round up + * @return the next-highest power of 2 from {@code v} + */ + public static int nextHighestPowerOfTwo(int v) { + // https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + return v; + } +}