From de11f1f90be9c3e286740fba2b3dfdc4e3c5d8bc Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Tue, 15 Jan 2019 11:01:45 -0200 Subject: [PATCH 1/8] trying to optimize blockconnectionstorage --- .../storage/BlockConnectionStorage.java | 124 +++++++++++++----- 1 file changed, 94 insertions(+), 30 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java index ad0a9e595..63ba9ecea 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java @@ -1,39 +1,62 @@ package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage; -import lombok.Data; -import lombok.EqualsAndHashCode; -import us.myles.ViaVersion.api.Pair; +import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.StoredObject; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.minecraft.Position; +import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; public class BlockConnectionStorage extends StoredObject { - private Map, Map> blockStorage = new HashMap<>(); + private Map> blockStorage = createLongObjectMap(); + + private static Class fastUtilLongObjectHashMap; + private static Class fastUtilLongShortHashMap; + private static Class nettyLongObjectHashMap; + + static { + try { + fastUtilLongObjectHashMap = Class.forName("it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap"); + Via.getPlatform().getLogger().info("Using FastUtil Long2ObjectOpenHashMap for block connections"); + } catch (ClassNotFoundException ignored) { + } + try { + fastUtilLongShortHashMap = Class.forName("it.unimi.dsi.fastutil.longs.Long2ShortOpenHashMap"); + Via.getPlatform().getLogger().info("Using FastUtil Long2ShortOpenHashMap for block connections"); + } catch (ClassNotFoundException ignored) { + } + if (fastUtilLongShortHashMap == null && fastUtilLongObjectHashMap == null) { + try { + nettyLongObjectHashMap = Class.forName("io.netty.util.collection.LongObjectHashMap"); + Via.getPlatform().getLogger().info("Using Netty LongObjectHashMap for block connections"); + } catch (ClassNotFoundException ignored) { + } + } + } public BlockConnectionStorage(UserConnection user) { super(user); } public void store(Position position, int blockState) { - Pair pair = getPair(position); - Map map = getChunkMap(pair); - map.put(new BlockPositon(position), blockState); + long pair = getChunkIndex(position); + Map map = getChunkMap(pair); + map.put(encodeBlockPos(position), (short) blockState); } public int get(Position position) { - Pair pair = getPair(position); - Map map = getChunkMap(pair); - BlockPositon blockPositon = new BlockPositon(position); + long pair = getChunkIndex(position); + Map map = getChunkMap(pair); + long blockPositon = encodeBlockPos(position); return map.containsKey(blockPositon) ? map.get(blockPositon) : 0; } public void remove(Position position) { - Pair pair = getPair(position); - Map map = getChunkMap(pair); - map.remove(new BlockPositon(position)); + long pair = getChunkIndex(position); + Map map = getChunkMap(pair); + map.remove(encodeBlockPos(position)); if (map.isEmpty()) { blockStorage.remove(pair); } @@ -44,33 +67,74 @@ public class BlockConnectionStorage extends StoredObject { } public void unloadChunk(int x, int z) { - blockStorage.remove(new Pair<>(x, z)); + blockStorage.remove(getChunkIndex(x, z)); } - private Map getChunkMap(Pair pair) { - Map map = blockStorage.get(pair); + private Map getChunkMap(long index) { + Map map = blockStorage.get(index); if (map == null) { - map = new HashMap<>(); - blockStorage.put(pair, map); + map = createLongShortMap(); + blockStorage.put(index, map); } return map; } - private Pair getPair(Position position) { - int chunkX = (int) (position.getX() >> 4); - int chunkZ = (int) (position.getZ() >> 4); - return new Pair<>(chunkX, chunkZ); + private long getChunkIndex(int x, int z) { + return (long) x << 32 | (z & 0xFFFFFFFFL); } - @EqualsAndHashCode - @Data - private class BlockPositon { - int x, y, z; + private long getChunkIndex(Position position) { + return getChunkIndex(position.getX().intValue(), position.getZ().intValue()); + } - public BlockPositon(Position position) { - x = position.getX().intValue(); - y = position.getY().intValue(); - z = position.getZ().intValue(); + private long encodeBlockPos(int x, int y, int z) { + return (((long) x & 0x3FFFFFF) << 38) | ((y & 0xFFF) << 26) | (z & 0x3FFFFFF); + } + + private long encodeBlockPos(Position pos) { + return encodeBlockPos(pos.getX().intValue(), pos.getY().intValue(), pos.getZ().intValue()); + } + + private Map createLongObjectMap() { + if (fastUtilLongObjectHashMap != null) { + try { + return (Map) fastUtilLongObjectHashMap.getConstructor().newInstance(); + } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { + e.printStackTrace(); + } } + if (nettyLongObjectHashMap != null) { + try { + return (Map) nettyLongObjectHashMap.getConstructor().newInstance(); + } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { + e.printStackTrace(); + } + } + return new HashMap<>(); + } + + private Map createLongShortMap() { + if (fastUtilLongShortHashMap != null) { + try { + return (Map) fastUtilLongShortHashMap.getConstructor().newInstance(); + } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { + e.printStackTrace(); + } + } + if (fastUtilLongObjectHashMap != null) { + try { + return (Map) fastUtilLongObjectHashMap.getConstructor().newInstance(); + } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { + e.printStackTrace(); + } + } + if (nettyLongObjectHashMap != null) { + try { + return (Map) nettyLongObjectHashMap.getConstructor().newInstance(); + } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { + e.printStackTrace(); + } + } + return new HashMap<>(); } } From fa1b56a7cf592f70808895856327bf75351cceaa Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Tue, 15 Jan 2019 13:15:34 -0200 Subject: [PATCH 2/8] use short --- .../storage/BlockConnectionStorage.java | 60 +++++++------------ 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java index 63ba9ecea..4a86dde0b 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java @@ -10,10 +10,10 @@ import java.util.HashMap; import java.util.Map; public class BlockConnectionStorage extends StoredObject { - private Map> blockStorage = createLongObjectMap(); + private Map> blockStorage = createLongObjectMap(); private static Class fastUtilLongObjectHashMap; - private static Class fastUtilLongShortHashMap; + private static Class fastUtilShortShortHashMap; private static Class nettyLongObjectHashMap; static { @@ -21,19 +21,17 @@ public class BlockConnectionStorage extends StoredObject { fastUtilLongObjectHashMap = Class.forName("it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap"); Via.getPlatform().getLogger().info("Using FastUtil Long2ObjectOpenHashMap for block connections"); } catch (ClassNotFoundException ignored) { - } - try { - fastUtilLongShortHashMap = Class.forName("it.unimi.dsi.fastutil.longs.Long2ShortOpenHashMap"); - Via.getPlatform().getLogger().info("Using FastUtil Long2ShortOpenHashMap for block connections"); - } catch (ClassNotFoundException ignored) { - } - if (fastUtilLongShortHashMap == null && fastUtilLongObjectHashMap == null) { try { nettyLongObjectHashMap = Class.forName("io.netty.util.collection.LongObjectHashMap"); Via.getPlatform().getLogger().info("Using Netty LongObjectHashMap for block connections"); - } catch (ClassNotFoundException ignored) { + } catch (ClassNotFoundException ignored2) { } } + try { + fastUtilShortShortHashMap = Class.forName("it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap"); + Via.getPlatform().getLogger().info("Using FastUtil Short2ShortOpenHashMap for block connections"); + } catch (ClassNotFoundException ignored) { + } } public BlockConnectionStorage(UserConnection user) { @@ -42,20 +40,20 @@ public class BlockConnectionStorage extends StoredObject { public void store(Position position, int blockState) { long pair = getChunkIndex(position); - Map map = getChunkMap(pair); + Map map = getChunkMap(pair); map.put(encodeBlockPos(position), (short) blockState); } public int get(Position position) { long pair = getChunkIndex(position); - Map map = getChunkMap(pair); - long blockPositon = encodeBlockPos(position); - return map.containsKey(blockPositon) ? map.get(blockPositon) : 0; + Map map = getChunkMap(pair); + short blockPosition = encodeBlockPos(position); + return map.containsKey(blockPosition) ? map.get(blockPosition) : 0; } public void remove(Position position) { long pair = getChunkIndex(position); - Map map = getChunkMap(pair); + Map map = getChunkMap(pair); map.remove(encodeBlockPos(position)); if (map.isEmpty()) { blockStorage.remove(pair); @@ -70,10 +68,10 @@ public class BlockConnectionStorage extends StoredObject { blockStorage.remove(getChunkIndex(x, z)); } - private Map getChunkMap(long index) { - Map map = blockStorage.get(index); + private Map getChunkMap(long index) { + Map map = blockStorage.get(index); if (map == null) { - map = createLongShortMap(); + map = createShortShortMap(); blockStorage.put(index, map); } return map; @@ -87,11 +85,11 @@ public class BlockConnectionStorage extends StoredObject { return getChunkIndex(position.getX().intValue(), position.getZ().intValue()); } - private long encodeBlockPos(int x, int y, int z) { - return (((long) x & 0x3FFFFFF) << 38) | ((y & 0xFFF) << 26) | (z & 0x3FFFFFF); + private short encodeBlockPos(int x, int y, int z) { + return (short) (y << 8 | x & 0xF << 4 | z & 0xF); } - private long encodeBlockPos(Position pos) { + private short encodeBlockPos(Position pos) { return encodeBlockPos(pos.getX().intValue(), pos.getY().intValue(), pos.getZ().intValue()); } @@ -113,24 +111,10 @@ public class BlockConnectionStorage extends StoredObject { return new HashMap<>(); } - private Map createLongShortMap() { - if (fastUtilLongShortHashMap != null) { + private Map createShortShortMap() { + if (fastUtilShortShortHashMap != null) { try { - return (Map) fastUtilLongShortHashMap.getConstructor().newInstance(); - } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { - e.printStackTrace(); - } - } - if (fastUtilLongObjectHashMap != null) { - try { - return (Map) fastUtilLongObjectHashMap.getConstructor().newInstance(); - } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { - e.printStackTrace(); - } - } - if (nettyLongObjectHashMap != null) { - try { - return (Map) nettyLongObjectHashMap.getConstructor().newInstance(); + return (Map) fastUtilShortShortHashMap.getConstructor().newInstance(); } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { e.printStackTrace(); } From 1325d5395032ae9cac54f0dc329cad08f0ec7ee7 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Tue, 15 Jan 2019 13:37:04 -0200 Subject: [PATCH 3/8] Don't use netty collections --- .../storage/BlockConnectionStorage.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java index 4a86dde0b..259e9dfe6 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java @@ -14,18 +14,13 @@ public class BlockConnectionStorage extends StoredObject { private static Class fastUtilLongObjectHashMap; private static Class fastUtilShortShortHashMap; - private static Class nettyLongObjectHashMap; static { try { fastUtilLongObjectHashMap = Class.forName("it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap"); Via.getPlatform().getLogger().info("Using FastUtil Long2ObjectOpenHashMap for block connections"); } catch (ClassNotFoundException ignored) { - try { - nettyLongObjectHashMap = Class.forName("io.netty.util.collection.LongObjectHashMap"); - Via.getPlatform().getLogger().info("Using Netty LongObjectHashMap for block connections"); - } catch (ClassNotFoundException ignored2) { - } + } try { fastUtilShortShortHashMap = Class.forName("it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap"); @@ -101,13 +96,6 @@ public class BlockConnectionStorage extends StoredObject { e.printStackTrace(); } } - if (nettyLongObjectHashMap != null) { - try { - return (Map) nettyLongObjectHashMap.getConstructor().newInstance(); - } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { - e.printStackTrace(); - } - } return new HashMap<>(); } From 193084927b5cc626114a61d561558d14f0368a0b Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Tue, 15 Jan 2019 14:21:37 -0200 Subject: [PATCH 4/8] store constructor --- .../storage/BlockConnectionStorage.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java index 259e9dfe6..6b9a7abdc 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java @@ -5,6 +5,7 @@ import us.myles.ViaVersion.api.data.StoredObject; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.minecraft.Position; +import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; @@ -12,20 +13,20 @@ import java.util.Map; public class BlockConnectionStorage extends StoredObject { private Map> blockStorage = createLongObjectMap(); - private static Class fastUtilLongObjectHashMap; - private static Class fastUtilShortShortHashMap; + private static Constructor fastUtilLongObjectHashMap; + private static Constructor fastUtilShortShortHashMap; static { try { - fastUtilLongObjectHashMap = Class.forName("it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap"); + fastUtilLongObjectHashMap = Class.forName("it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap").getConstructor(); Via.getPlatform().getLogger().info("Using FastUtil Long2ObjectOpenHashMap for block connections"); - } catch (ClassNotFoundException ignored) { + } catch (ClassNotFoundException | NoSuchMethodException ignored) { } try { - fastUtilShortShortHashMap = Class.forName("it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap"); + fastUtilShortShortHashMap = Class.forName("it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap").getConstructor(); Via.getPlatform().getLogger().info("Using FastUtil Short2ShortOpenHashMap for block connections"); - } catch (ClassNotFoundException ignored) { + } catch (ClassNotFoundException | NoSuchMethodException ignored) { } } @@ -91,8 +92,8 @@ public class BlockConnectionStorage extends StoredObject { private Map createLongObjectMap() { if (fastUtilLongObjectHashMap != null) { try { - return (Map) fastUtilLongObjectHashMap.getConstructor().newInstance(); - } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { + return (Map) fastUtilLongObjectHashMap.newInstance(); + } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { e.printStackTrace(); } } @@ -102,8 +103,8 @@ public class BlockConnectionStorage extends StoredObject { private Map createShortShortMap() { if (fastUtilShortShortHashMap != null) { try { - return (Map) fastUtilShortShortHashMap.getConstructor().newInstance(); - } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { + return (Map) fastUtilShortShortHashMap.newInstance(); + } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { e.printStackTrace(); } } From 2285c453dad9c4148fda473720e0e03df932fe52 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Tue, 15 Jan 2019 15:43:10 -0200 Subject: [PATCH 5/8] fixed encodeblockpos, use map --- .../storage/BlockConnectionStorage.java | 63 ++++++++----------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java index 6b9a7abdc..96bdb45c9 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java @@ -7,26 +7,21 @@ import us.myles.ViaVersion.api.minecraft.Position; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; public class BlockConnectionStorage extends StoredObject { - private Map> blockStorage = createLongObjectMap(); + private Map blockStorage = createLongObjectMap(); + private static short[] short4096 = new short[4096]; private static Constructor fastUtilLongObjectHashMap; - private static Constructor fastUtilShortShortHashMap; static { try { fastUtilLongObjectHashMap = Class.forName("it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap").getConstructor(); Via.getPlatform().getLogger().info("Using FastUtil Long2ObjectOpenHashMap for block connections"); } catch (ClassNotFoundException | NoSuchMethodException ignored) { - - } - try { - fastUtilShortShortHashMap = Class.forName("it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap").getConstructor(); - Via.getPlatform().getLogger().info("Using FastUtil Short2ShortOpenHashMap for block connections"); - } catch (ClassNotFoundException | NoSuchMethodException ignored) { } } @@ -35,23 +30,24 @@ public class BlockConnectionStorage extends StoredObject { } public void store(Position position, int blockState) { - long pair = getChunkIndex(position); - Map map = getChunkMap(pair); - map.put(encodeBlockPos(position), (short) blockState); + long pair = getChunkSectionIndex(position); + short[] map = getChunkSection(pair); + map[encodeBlockPos(position)] = (short) blockState; } public int get(Position position) { - long pair = getChunkIndex(position); - Map map = getChunkMap(pair); + long pair = getChunkSectionIndex(position); + short[] map = blockStorage.get(pair); + if (map == null) return 0; short blockPosition = encodeBlockPos(position); - return map.containsKey(blockPosition) ? map.get(blockPosition) : 0; + return map[blockPosition]; } public void remove(Position position) { - long pair = getChunkIndex(position); - Map map = getChunkMap(pair); - map.remove(encodeBlockPos(position)); - if (map.isEmpty()) { + long pair = getChunkSectionIndex(position); + short[] map = getChunkSection(pair); + map[encodeBlockPos(position)] = 0; + if (Arrays.equals(short4096, map)) { blockStorage.remove(pair); } } @@ -61,28 +57,30 @@ public class BlockConnectionStorage extends StoredObject { } public void unloadChunk(int x, int z) { - blockStorage.remove(getChunkIndex(x, z)); + for (int y = 0; y < 256; y += 16) { + blockStorage.remove(getChunkSectionIndex(x, y, z)); + } } - private Map getChunkMap(long index) { - Map map = blockStorage.get(index); + private short[] getChunkSection(long index) { + short[] map = blockStorage.get(index); if (map == null) { - map = createShortShortMap(); + map = new short[4096]; blockStorage.put(index, map); } return map; } - private long getChunkIndex(int x, int z) { - return (long) x << 32 | (z & 0xFFFFFFFFL); + private long getChunkSectionIndex(int x, int y, int z) { + return (((x >> 4) & 0x3FFFFFFL) << 38) | (((y >> 4) & 0xFFFL) << 26) | ((z >> 4) & 0x3FFFFFFL); } - private long getChunkIndex(Position position) { - return getChunkIndex(position.getX().intValue(), position.getZ().intValue()); + private long getChunkSectionIndex(Position position) { + return getChunkSectionIndex(position.getX().intValue(), position.getY().intValue(), position.getZ().intValue()); } private short encodeBlockPos(int x, int y, int z) { - return (short) (y << 8 | x & 0xF << 4 | z & 0xF); + return (short) (((y & 0xF) << 8) | ((x & 0xF) << 4) | (z & 0xF)); } private short encodeBlockPos(Position pos) { @@ -99,15 +97,4 @@ public class BlockConnectionStorage extends StoredObject { } return new HashMap<>(); } - - private Map createShortShortMap() { - if (fastUtilShortShortHashMap != null) { - try { - return (Map) fastUtilShortShortHashMap.newInstance(); - } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { - e.printStackTrace(); - } - } - return new HashMap<>(); - } } From d5f65eceb0b0d286687c773d3706b66541008193 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Tue, 15 Jan 2019 15:45:18 -0200 Subject: [PATCH 6/8] don't create chunksection on remove --- .../protocol1_13to1_12_2/storage/BlockConnectionStorage.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java index 96bdb45c9..2972b33ad 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java @@ -45,7 +45,8 @@ public class BlockConnectionStorage extends StoredObject { public void remove(Position position) { long pair = getChunkSectionIndex(position); - short[] map = getChunkSection(pair); + short[] map = blockStorage.get(pair); + if (map == null) return; map[encodeBlockPos(position)] = 0; if (Arrays.equals(short4096, map)) { blockStorage.remove(pair); From f45a727396392e4a81f73d225ac72e5fc5a3bb05 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Thu, 17 Jan 2019 04:30:34 -0200 Subject: [PATCH 7/8] remove short array used for checking if array is empty --- .../storage/BlockConnectionStorage.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java index 2972b33ad..b7e5c5da6 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java @@ -7,13 +7,11 @@ import us.myles.ViaVersion.api.minecraft.Position; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; public class BlockConnectionStorage extends StoredObject { private Map blockStorage = createLongObjectMap(); - private static short[] short4096 = new short[4096]; private static Constructor fastUtilLongObjectHashMap; @@ -48,9 +46,10 @@ public class BlockConnectionStorage extends StoredObject { short[] map = blockStorage.get(pair); if (map == null) return; map[encodeBlockPos(position)] = 0; - if (Arrays.equals(short4096, map)) { - blockStorage.remove(pair); + for (short entry : map) { + if (entry != 0) return; } + blockStorage.remove(pair); } public void clear() { From f6d7976eff7f95ce7c98e56b3fa681f5e3edbfc9 Mon Sep 17 00:00:00 2001 From: creeper123123321 Date: Thu, 17 Jan 2019 14:49:08 -0200 Subject: [PATCH 8/8] Use old ids and byte[] + NibbleArray for block connections --- .../api/minecraft/chunks/NibbleArray.java | 7 ++- .../packets/WorldPackets.java | 5 +- .../storage/BlockConnectionStorage.java | 58 +++++++++++++++---- 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java index 8245d2a8c..4cfeddccc 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java +++ b/common/src/main/java/us/myles/ViaVersion/api/minecraft/chunks/NibbleArray.java @@ -67,11 +67,12 @@ public class NibbleArray { * @param value The desired value */ public void set(int index, int value) { - index /= 2; if (index % 2 == 0) { - handle[index] = (byte) (handle[index] & 0xF0 | value & 0xF); + index /= 2; + handle[index] = (byte) ((handle[index] & 0xF0) | (value & 0xF)); } else { - handle[index] = (byte) (handle[index] & 0xF | (value & 0xF) << 4); + index /= 2; + handle[index] = (byte) ((handle[index] & 0xF) | ((value & 0xF) << 4)); } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java index 0c932eaf6..18aea5bab 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/WorldPackets.java @@ -175,12 +175,13 @@ public class WorldPackets { if (Via.getConfig().isServersideBlockConnections()) { UserConnection userConnection = wrapper.user(); + + ConnectionData.updateBlockStorage(userConnection, position, newId); + if (ConnectionData.connects(newId)) { newId = ConnectionData.connect(userConnection, position, newId); } - ConnectionData.updateBlockStorage(userConnection, position, newId); - ConnectionData.update(userConnection, position); } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java index b7e5c5da6..1694e2af9 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/storage/BlockConnectionStorage.java @@ -1,9 +1,13 @@ package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage; +import us.myles.ViaVersion.api.Pair; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.StoredObject; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.minecraft.Position; +import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.WorldPackets; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -11,9 +15,10 @@ import java.util.HashMap; import java.util.Map; public class BlockConnectionStorage extends StoredObject { - private Map blockStorage = createLongObjectMap(); + private Map> blockStorage = createLongObjectMap(); private static Constructor fastUtilLongObjectHashMap; + private static HashMap reverseBlockMappings; static { try { @@ -21,6 +26,11 @@ public class BlockConnectionStorage extends StoredObject { Via.getPlatform().getLogger().info("Using FastUtil Long2ObjectOpenHashMap for block connections"); } catch (ClassNotFoundException | NoSuchMethodException ignored) { } + reverseBlockMappings = new HashMap<>(); + for (int i = 0; i < 4096; i++) { + int newBlock = MappingData.blockMappings.getNewBlock(i); + if (newBlock != -1) reverseBlockMappings.put((short) newBlock, (short) i); + } } public BlockConnectionStorage(UserConnection user) { @@ -28,25 +38,48 @@ public class BlockConnectionStorage extends StoredObject { } public void store(Position position, int blockState) { + Short mapping = reverseBlockMappings.get((short) blockState); + if (mapping == null) return; + blockState = mapping; long pair = getChunkSectionIndex(position); - short[] map = getChunkSection(pair); - map[encodeBlockPos(position)] = (short) blockState; + Pair map = getChunkSection(pair, (blockState & 0xF) != 0); + int blockIndex = encodeBlockPos(position); + map.getKey()[blockIndex] = (byte) (blockState >> 4); + NibbleArray nibbleArray = map.getValue(); + if (nibbleArray != null) nibbleArray.set(blockIndex, blockState); } public int get(Position position) { long pair = getChunkSectionIndex(position); - short[] map = blockStorage.get(pair); + Pair map = blockStorage.get(pair); if (map == null) return 0; short blockPosition = encodeBlockPos(position); - return map[blockPosition]; + NibbleArray nibbleArray = map.getValue(); + return WorldPackets.toNewId( + ((map.getKey()[blockPosition] & 0xFF) << 4) + | (nibbleArray == null ? 0 : nibbleArray.get(blockPosition)) + ); } public void remove(Position position) { long pair = getChunkSectionIndex(position); - short[] map = blockStorage.get(pair); + Pair map = blockStorage.get(pair); if (map == null) return; - map[encodeBlockPos(position)] = 0; - for (short entry : map) { + int blockIndex = encodeBlockPos(position); + NibbleArray nibbleArray = map.getValue(); + if (nibbleArray != null) { + nibbleArray.set(blockIndex, 0); + boolean allZero = true; + for (int i = 0; i < 4096; i++) { + if (nibbleArray.get(i) != 0) { + allZero = false; + break; + } + } + if (allZero) map.setValue(null); + } + map.getKey()[blockIndex] = 0; + for (short entry : map.getKey()) { if (entry != 0) return; } blockStorage.remove(pair); @@ -62,12 +95,15 @@ public class BlockConnectionStorage extends StoredObject { } } - private short[] getChunkSection(long index) { - short[] map = blockStorage.get(index); + private Pair getChunkSection(long index, boolean requireNibbleArray) { + Pair map = blockStorage.get(index); if (map == null) { - map = new short[4096]; + map = new Pair<>(new byte[4096], null); blockStorage.put(index, map); } + if (map.getValue() == null && requireNibbleArray) { + map.setValue(new NibbleArray(4096)); + } return map; }