mirror of
https://github.com/YatopiaMC/Yatopia.git
synced 2024-12-01 15:13:24 +01:00
939aa76bf3
Upstream/An Sidestream has released updates that appears to apply and compile correctly This update has NOT been tested by YatopiaMC and as with ANY update, please do your own testing. Tuinity Changes: f32fe9a Updated Upstream (Paper) Airplane Changes: 125aff7 Updated Upstream (Tuinity) Origami Changes: 756162f Update Paper 2f9721c Update snakeyaml and enable comment loading/saving
197 lines
9.0 KiB
Diff
197 lines
9.0 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: 2No2Name <50278648+2No2Name@users.noreply.github.com>
|
|
Date: Mon, 15 Feb 2021 14:58:55 -0500
|
|
Subject: [PATCH] lithium: optimize `BlockPos.iterateOutwards` by caching
|
|
offsets
|
|
|
|
Code taken from: https://github.com/CaffeineMC/lithium-fabric/pull/123 by 2No2Name licenced under the LGPLv3 License
|
|
|
|
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/IterateOutwardsCache.java b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/IterateOutwardsCache.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..50e9df6056f713b2f1eaf0cb4a23875e0c6c2e2c
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/IterateOutwardsCache.java
|
|
@@ -0,0 +1,72 @@
|
|
+package me.jellysquid.mods.lithium.common.cached_blockpos_iteration;
|
|
+
|
|
+import it.unimi.dsi.fastutil.longs.LongArrayList;
|
|
+import it.unimi.dsi.fastutil.longs.LongList;
|
|
+import net.minecraft.core.BlockPosition;
|
|
+
|
|
+import java.util.Iterator;
|
|
+import java.util.Random;
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
+
|
|
+/**
|
|
+ * @author 2No2Name, original implemenation by SuperCoder7979 and Gegy1000
|
|
+ */
|
|
+public class IterateOutwardsCache {
|
|
+ //POS_ZERO must not be replaced with BlockPos.ORIGIN, otherwise iterateOutwards at BlockPos.ORIGIN will not use the cache
|
|
+ public static final BlockPosition POS_ZERO = new BlockPosition(0,0,0);
|
|
+
|
|
+
|
|
+ private final ConcurrentHashMap<Long, LongArrayList> table;
|
|
+ private final int capacity;
|
|
+ private final Random random;
|
|
+
|
|
+ public IterateOutwardsCache(int capacity) {
|
|
+ this.capacity = capacity;
|
|
+ this.table = new ConcurrentHashMap<>(31);
|
|
+ this.random = new Random();
|
|
+ }
|
|
+
|
|
+ private void fillPositionsWithIterateOutwards(LongList entry, int xRange, int yRange, int zRange) {
|
|
+ // Add all positions to the cached list
|
|
+ for (BlockPosition pos : BlockPosition.iterateOutwards(POS_ZERO, xRange, yRange, zRange)) {
|
|
+ entry.add(pos.asLong());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public LongList getOrCompute(int xRange, int yRange, int zRange) {
|
|
+ long key = BlockPosition.asLong(xRange, yRange, zRange);
|
|
+
|
|
+ LongArrayList entry = this.table.get(key);
|
|
+ if (entry != null) {
|
|
+ return entry;
|
|
+ }
|
|
+
|
|
+ // Cache miss: compute and store
|
|
+ entry = new LongArrayList(128);
|
|
+
|
|
+ this.fillPositionsWithIterateOutwards(entry, xRange, yRange, zRange);
|
|
+
|
|
+ //decrease the array size, as of now it won't be modified anymore anyways
|
|
+ entry.trim();
|
|
+
|
|
+ //this might overwrite an entry as the same entry could have been computed and added during this thread's computation
|
|
+ //we do not use computeIfAbsent, as it can delay other threads for too long
|
|
+ Object previousEntry = this.table.put(key, entry);
|
|
+
|
|
+
|
|
+ if (previousEntry == null && this.table.size() > this.capacity) {
|
|
+ //prevent a memory leak by randomly removing about 1/8th of the elements when the exceed the desired capacity is exceeded
|
|
+ final Iterator<Long> iterator = this.table.keySet().iterator();
|
|
+ //prevent an unlikely infinite loop caused by another thread filling the table concurrently using counting
|
|
+ for (int i = -this.capacity; iterator.hasNext() && i < 5; i++) {
|
|
+ Long key2 = iterator.next();
|
|
+ //random is not threadsafe, but it doesn't matter here, because we don't need quality random numbers
|
|
+ if (this.random.nextInt(8) == 0 && key2 != key) {
|
|
+ iterator.remove();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return entry;
|
|
+ }
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/LongList2BlockPosMutableIterable.java b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/LongList2BlockPosMutableIterable.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..e2e4f7968a399b4641df07b2931fff6dbc85ddb3
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/LongList2BlockPosMutableIterable.java
|
|
@@ -0,0 +1,47 @@
|
|
+package me.jellysquid.mods.lithium.common.cached_blockpos_iteration;
|
|
+
|
|
+import it.unimi.dsi.fastutil.longs.LongIterator;
|
|
+import it.unimi.dsi.fastutil.longs.LongList;
|
|
+import net.minecraft.core.BlockPosition;
|
|
+
|
|
+import java.util.Iterator;
|
|
+
|
|
+/**
|
|
+ * @author 2No2Name
|
|
+ */
|
|
+public class LongList2BlockPosMutableIterable implements Iterable<BlockPosition> {
|
|
+
|
|
+ private final LongList positions;
|
|
+ private final int xOffset, yOffset, zOffset;
|
|
+
|
|
+ public LongList2BlockPosMutableIterable(BlockPosition offset, LongList posList) {
|
|
+ this.xOffset = offset.getX();
|
|
+ this.yOffset = offset.getY();
|
|
+ this.zOffset = offset.getZ();
|
|
+ this.positions = posList;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Iterator<BlockPosition> iterator() {
|
|
+ return new Iterator<BlockPosition>() {
|
|
+
|
|
+ private final LongIterator it = LongList2BlockPosMutableIterable.this.positions.iterator();
|
|
+ private final BlockPosition.MutableBlockPosition pos = new BlockPosition.MutableBlockPosition();
|
|
+
|
|
+ @Override
|
|
+ public boolean hasNext() {
|
|
+ return it.hasNext();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public BlockPosition next() {
|
|
+ long nextPos = this.it.nextLong();
|
|
+ return this.pos.setValues(
|
|
+ LongList2BlockPosMutableIterable.this.xOffset + BlockPosition.unpackLongX(nextPos),
|
|
+ LongList2BlockPosMutableIterable.this.yOffset + BlockPosition.unpackLongY(nextPos),
|
|
+ LongList2BlockPosMutableIterable.this.zOffset + BlockPosition.unpackLongZ(nextPos));
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/src/main/java/net/minecraft/core/BlockPosition.java b/src/main/java/net/minecraft/core/BlockPosition.java
|
|
index 84e753804f58cbbe1b3b30aa1fe1fecd739a1551..e3ac546214793cb9c5af19046d20216095c6cc02 100644
|
|
--- a/src/main/java/net/minecraft/core/BlockPosition.java
|
|
+++ b/src/main/java/net/minecraft/core/BlockPosition.java
|
|
@@ -18,10 +18,16 @@ import net.minecraft.world.phys.Vec3D;
|
|
import org.apache.commons.lang3.Validate;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
+import me.jellysquid.mods.lithium.common.cached_blockpos_iteration.IterateOutwardsCache; // Yatopia
|
|
+import me.jellysquid.mods.lithium.common.cached_blockpos_iteration.LongList2BlockPosMutableIterable; // Yatopia
|
|
+import it.unimi.dsi.fastutil.longs.LongList; // Yatopia
|
|
|
|
@Immutable
|
|
public class BlockPosition extends BaseBlockPosition {
|
|
|
|
+ private static final IterateOutwardsCache ITERATE_OUTWARDS_CACHE = new IterateOutwardsCache(50); // Yatopia
|
|
+ private static final LongList HOGLIN_PIGLIN_CACHE = ITERATE_OUTWARDS_CACHE.getOrCompute(8, 4, 8); // Yatopia
|
|
+
|
|
public static final Codec<BlockPosition> a = Codec.INT_STREAM.comapFlatMap((intstream) -> {
|
|
return SystemUtils.a(intstream, 3).map((aint) -> {
|
|
return new BlockPosition(aint[0], aint[1], aint[2]);
|
|
@@ -71,14 +77,17 @@ public class BlockPosition extends BaseBlockPosition {
|
|
return a((int) (i >> 38) + j, (int) ((i << 52) >> 52) + k, (int) ((i << 26) >> 38) + l); // Paper - simplify/inline
|
|
}
|
|
|
|
+ public static int unpackLongX(long i) { return BlockPosition.b(i); } // Yatopia - OBFHELPER
|
|
public static int b(long i) {
|
|
return (int) (i >> 38); // Paper - simplify/inline
|
|
}
|
|
|
|
+ public static int unpackLongY(long i) { return BlockPosition.c(i); } // Yatopia - OBFHELPER
|
|
public static int c(long i) {
|
|
return (int) ((i << 52) >> 52); // Paper - simplify/inline
|
|
}
|
|
|
|
+ public static int unpackLongZ(long i) { return BlockPosition.d(i); } // Yatopia - OBFHELPER
|
|
public static int d(long i) {
|
|
return (int) ((i << 26) >> 38); // Paper - simplify/inline
|
|
}
|
|
@@ -259,7 +268,15 @@ public class BlockPosition extends BaseBlockPosition {
|
|
};
|
|
}
|
|
|
|
+ public static Iterable<BlockPosition> iterateOutwards(BlockPosition blockposition, int p_i, int p_j, int p_k) { return BlockPosition.a(blockposition, p_i, p_j, p_k); } // Yatopia - OBFHELPER
|
|
public static Iterable<BlockPosition> a(BlockPosition blockposition, int p_i, int p_j, int p_k) { // Paper - decompile issues - variable name conflicts to inner class field refs
|
|
+ // Yatopia start - lithium: optimize `BlockPos.iterateOutwards` by caching offsets
|
|
+ if (blockposition != me.jellysquid.mods.lithium.common.cached_blockpos_iteration.IterateOutwardsCache.POS_ZERO) {
|
|
+ final LongList positions = p_i == 8 && p_j == 4 && p_k == 8 ? HOGLIN_PIGLIN_CACHE : ITERATE_OUTWARDS_CACHE.getOrCompute(p_i, p_j, p_j);
|
|
+ return new LongList2BlockPosMutableIterable(blockposition, positions);
|
|
+ }
|
|
+ // Yatopia end
|
|
+
|
|
int l_decompiled = p_i + p_j + p_k; // Paper - decompile issues
|
|
int i1 = blockposition.getX();
|
|
int j1 = blockposition.getY();
|