From 66a5829c3eed783984b9552512680ce5452cda6f Mon Sep 17 00:00:00 2001 From: themode Date: Fri, 8 Jan 2021 15:33:48 +0100 Subject: [PATCH] Implement offset for RelativeBlockBatch + optimization --- .../instance/batch/AbsoluteBlockBatch.java | 5 +- .../instance/batch/RelativeBlockBatch.java | 59 +++++++++++++------ 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/main/java/net/minestom/server/instance/batch/AbsoluteBlockBatch.java b/src/main/java/net/minestom/server/instance/batch/AbsoluteBlockBatch.java index 2742748e8..986192f9b 100644 --- a/src/main/java/net/minestom/server/instance/batch/AbsoluteBlockBatch.java +++ b/src/main/java/net/minestom/server/instance/batch/AbsoluteBlockBatch.java @@ -9,7 +9,6 @@ import net.minestom.server.utils.chunk.ChunkUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /** @@ -85,8 +84,8 @@ public class AbsoluteBlockBatch implements Batch { protected void apply(@NotNull InstanceContainer instance, @Nullable Runnable callback, boolean safeCallback) { synchronized (chunkBatchesMap) { AtomicInteger counter = new AtomicInteger(); - for (Map.Entry entry : chunkBatchesMap.long2ObjectEntrySet()) { - final long chunkIndex = entry.getKey(); + for (Long2ObjectMap.Entry entry : chunkBatchesMap.long2ObjectEntrySet()) { + final long chunkIndex = entry.getLongKey(); final int chunkX = ChunkUtils.getChunkCoordX(chunkIndex); final int chunkZ = ChunkUtils.getChunkCoordZ(chunkIndex); final ChunkBatch batch = entry.getValue(); diff --git a/src/main/java/net/minestom/server/instance/batch/RelativeBlockBatch.java b/src/main/java/net/minestom/server/instance/batch/RelativeBlockBatch.java index a673c9ca4..e4c2f86d7 100644 --- a/src/main/java/net/minestom/server/instance/batch/RelativeBlockBatch.java +++ b/src/main/java/net/minestom/server/instance/batch/RelativeBlockBatch.java @@ -1,6 +1,9 @@ package net.minestom.server.instance.batch; -import it.unimi.dsi.fastutil.longs.*; +import it.unimi.dsi.fastutil.longs.Long2IntMap; +import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minestom.server.data.Data; import net.minestom.server.instance.InstanceContainer; import net.minestom.server.utils.BlockPosition; @@ -8,8 +11,6 @@ import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Map; - public class RelativeBlockBatch implements Batch { // relative pos format: nothing/relative x/relative y/relative z (16/16/16/16 bits) @@ -21,8 +22,27 @@ public class RelativeBlockBatch implements Batch { // relative pos - data private final Long2ObjectMap blockDataMap = new Long2ObjectOpenHashMap<>(); + private volatile boolean firstEntry = true; + private int offsetX, offsetY, offsetZ; + @Override public void setSeparateBlocks(int x, int y, int z, short blockStateId, short customBlockId, @Nullable Data data) { + + // Save the offsets if it is the first entry + if (!firstEntry) { + this.firstEntry = true; + + this.offsetX = x; + this.offsetY = y; + this.offsetZ = z; + } + + // Subtract offset + x -= offsetX; + y -= offsetY; + z -= offsetZ; + + // Verify that blocks are not too far from each other Check.argCondition(Math.abs(x) > Short.MAX_VALUE, "Relative x position may not be more than 16 bits long."); Check.argCondition(Math.abs(y) > Short.MAX_VALUE, "Relative y position may not be more than 16 bits long."); Check.argCondition(Math.abs(z) > Short.MAX_VALUE, "Relative z position may not be more than 16 bits long."); @@ -34,11 +54,12 @@ public class RelativeBlockBatch implements Batch { final int block = (blockStateId << 16) | customBlockId; synchronized (blockIdMap) { this.blockIdMap.put(pos, block); - } - if (data != null) { - synchronized (blockDataMap) { - this.blockDataMap.put(pos, data); + // Save data if present + if (data != null) { + synchronized (blockDataMap) { + this.blockDataMap.put(pos, data); + } } } } @@ -68,18 +89,18 @@ public class RelativeBlockBatch implements Batch { } protected void apply(@NotNull InstanceContainer instance, int x, int y, int z, @Nullable Runnable callback, boolean safeCallback) { - final AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); + AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); synchronized (blockIdMap) { - for (Map.Entry entry : blockIdMap.long2IntEntrySet()) { - long pos = entry.getKey(); - short relZ = (short) (pos & 0xFFFF); - short relY = (short) ((pos >> 16) & 0xFFFF); - short relX = (short) ((pos >> 32) & 0xFFFF); + for (Long2IntMap.Entry entry : blockIdMap.long2IntEntrySet()) { + final long pos = entry.getLongKey(); + final short relZ = (short) (pos & 0xFFFF); + final short relY = (short) ((pos >> 16) & 0xFFFF); + final short relX = (short) ((pos >> 32) & 0xFFFF); - int ids = entry.getValue(); - short customBlockId = (short) (ids & 0xFFFF); - short blockStateId = (short) ((ids >> 16) & 0xFFFF); + final int ids = entry.getIntValue(); + final short customBlockId = (short) (ids & 0xFFFF); + final short blockStateId = (short) ((ids >> 16) & 0xFFFF); Data data = null; if (!blockDataMap.isEmpty()) { @@ -88,7 +109,11 @@ public class RelativeBlockBatch implements Batch { } } - batch.setSeparateBlocks(x + relX, y + relY, z + relZ, blockStateId, customBlockId, data); + final int finalX = x + offsetX + relX; + final int finalY = y + offsetY + relY; + final int finalZ = z + offsetZ + relZ; + + batch.setSeparateBlocks(finalX, finalY, finalZ, blockStateId, customBlockId, data); } }