diff --git a/build.gradle.kts b/build.gradle.kts index a2010db..eb0b91e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -92,4 +92,4 @@ paperweight { serverOutputDir.set(layout.projectDirectory.dir("Luminol-Server")) } } -} \ No newline at end of file +} diff --git a/patches/server/0020-Pufferfish-Improve-fluid-direction-caching.patch b/patches/server/0020-Pufferfish-Improve-fluid-direction-caching.patch new file mode 100644 index 0000000..80a7eac --- /dev/null +++ b/patches/server/0020-Pufferfish-Improve-fluid-direction-caching.patch @@ -0,0 +1,237 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: M2ke4U <79621885+MrHua269@users.noreply.github.com> +Date: Sun, 26 Nov 2023 16:00:59 +0800 +Subject: [PATCH] Pufferfish Improve fluid direction caching + + +diff --git a/src/main/java/gg/airplane/structs/FluidDirectionCache.java b/src/main/java/gg/airplane/structs/FluidDirectionCache.java +new file mode 100644 +index 0000000000000000000000000000000000000000..aa8467b9dda1f7707e41f50ac7b3e9d7343723ec +--- /dev/null ++++ b/src/main/java/gg/airplane/structs/FluidDirectionCache.java +@@ -0,0 +1,136 @@ ++package gg.airplane.structs; ++ ++import it.unimi.dsi.fastutil.HashCommon; ++ ++/** ++ * This is a replacement for the cache used in FluidTypeFlowing. ++ * The requirements for the previous cache were: ++ * - Store 200 entries ++ * - Look for the flag in the cache ++ * - If it exists, move to front of cache ++ * - If it doesn't exist, remove last entry in cache and insert in front ++ * ++ * This class accomplishes something similar, however has a few different ++ * requirements put into place to make this more optimize: ++ * ++ * - maxDistance is the most amount of entries to be checked, instead ++ * of having to check the entire list. ++ * - In combination with that, entries are all tracked by age and how ++ * frequently they're used. This enables us to remove old entries, ++ * without constantly shifting any around. ++ * ++ * Usage of the previous map would have to reset the head every single usage, ++ * shifting the entire map. Here, nothing happens except an increment when ++ * the cache is hit, and when it needs to replace an old element only a single ++ * element is modified. ++ */ ++public class FluidDirectionCache { ++ ++ private static class FluidDirectionEntry { ++ private final T data; ++ private final boolean flag; ++ private int uses = 0; ++ private int age = 0; ++ ++ private FluidDirectionEntry(T data, boolean flag) { ++ this.data = data; ++ this.flag = flag; ++ } ++ ++ public int getValue() { ++ return this.uses - (this.age >> 1); // age isn't as important as uses ++ } ++ ++ public void incrementUses() { ++ this.uses = this.uses + 1 & Integer.MAX_VALUE; ++ } ++ ++ public void incrementAge() { ++ this.age = this.age + 1 & Integer.MAX_VALUE; ++ } ++ } ++ ++ private final FluidDirectionEntry[] entries; ++ private final int mask; ++ private final int maxDistance; // the most amount of entries to check for a value ++ ++ public FluidDirectionCache(int size) { ++ int arraySize = HashCommon.nextPowerOfTwo(size); ++ this.entries = new FluidDirectionEntry[arraySize]; ++ this.mask = arraySize - 1; ++ this.maxDistance = Math.min(arraySize, 4); ++ } ++ ++ public Boolean getValue(T data) { ++ FluidDirectionEntry curr; ++ int pos; ++ ++ if ((curr = this.entries[pos = HashCommon.mix(data.hashCode()) & this.mask]) == null) { ++ return null; ++ } else if (data.equals(curr.data)) { ++ curr.incrementUses(); ++ return curr.flag; ++ } ++ ++ int checked = 1; // start at 1 because we already checked the first spot above ++ ++ while ((curr = this.entries[pos = (pos + 1) & this.mask]) != null) { ++ if (data.equals(curr.data)) { ++ curr.incrementUses(); ++ return curr.flag; ++ } else if (++checked >= this.maxDistance) { ++ break; ++ } ++ } ++ ++ return null; ++ } ++ ++ public void putValue(T data, boolean flag) { ++ FluidDirectionEntry curr; ++ int pos; ++ ++ if ((curr = this.entries[pos = HashCommon.mix(data.hashCode()) & this.mask]) == null) { ++ this.entries[pos] = new FluidDirectionEntry<>(data, flag); // add ++ return; ++ } else if (data.equals(curr.data)) { ++ curr.incrementUses(); ++ return; ++ } ++ ++ int checked = 1; // start at 1 because we already checked the first spot above ++ ++ while ((curr = this.entries[pos = (pos + 1) & this.mask]) != null) { ++ if (data.equals(curr.data)) { ++ curr.incrementUses(); ++ return; ++ } else if (++checked >= this.maxDistance) { ++ this.forceAdd(data, flag); ++ return; ++ } ++ } ++ ++ this.entries[pos] = new FluidDirectionEntry<>(data, flag); // add ++ } ++ ++ private void forceAdd(T data, boolean flag) { ++ int expectedPos = HashCommon.mix(data.hashCode()) & this.mask; ++ ++ int toRemovePos = expectedPos; ++ FluidDirectionEntry entryToRemove = this.entries[toRemovePos]; ++ ++ for (int i = expectedPos + 1; i < expectedPos + this.maxDistance; i++) { ++ int pos = i & this.mask; ++ FluidDirectionEntry entry = this.entries[pos]; ++ if (entry.getValue() < entryToRemove.getValue()) { ++ toRemovePos = pos; ++ entryToRemove = entry; ++ } ++ ++ entry.incrementAge(); // use this as a mechanism to age the other entries ++ } ++ ++ // remove the least used/oldest entry ++ this.entries[toRemovePos] = new FluidDirectionEntry(data, flag); ++ } ++} +diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..c55f51e6db55f9fa66f53eef0e7a56af5f81d742 100644 +--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java ++++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +@@ -45,6 +45,8 @@ public abstract class FlowingFluid extends Fluid { + public static final BooleanProperty FALLING = BlockStateProperties.FALLING; + public static final IntegerProperty LEVEL = BlockStateProperties.LEVEL_FLOWING; + private static final int CACHE_SIZE = 200; ++ // Pufferfish start - use our own cache ++ /* + private static final ThreadLocal> OCCLUSION_CACHE = ThreadLocal.withInitial(() -> { + Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap = new Object2ByteLinkedOpenHashMap(200) { + protected void rehash(int i) {} +@@ -53,6 +55,14 @@ public abstract class FlowingFluid extends Fluid { + object2bytelinkedopenhashmap.defaultReturnValue((byte) 127); + return object2bytelinkedopenhashmap; + }); ++ */ ++ ++ private static final ThreadLocal> localFluidDirectionCache = ThreadLocal.withInitial(() -> { ++ // Pufferfish todo - mess with this number for performance ++ // with 2048 it seems very infrequent on a small world that it has to remove old entries ++ return new gg.airplane.structs.FluidDirectionCache<>(2048); ++ }); ++ // Pufferfish end + private final Map shapes = Maps.newIdentityHashMap(); + + public FlowingFluid() {} +@@ -252,6 +262,8 @@ public abstract class FlowingFluid extends Fluid { + return false; + } + // Paper end - optimise collisions ++ // Pufferfish start - modify to use our cache ++ /* + Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap; + + if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) { +@@ -259,9 +271,16 @@ public abstract class FlowingFluid extends Fluid { + } else { + object2bytelinkedopenhashmap = null; + } ++ */ ++ gg.airplane.structs.FluidDirectionCache cache = null; ++ ++ if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) { ++ cache = localFluidDirectionCache.get(); ++ } + + Block.BlockStatePairKey block_a; + ++ /* + if (object2bytelinkedopenhashmap != null) { + block_a = new Block.BlockStatePairKey(state, fromState, face); + byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(block_a); +@@ -272,11 +291,22 @@ public abstract class FlowingFluid extends Fluid { + } else { + block_a = null; + } ++ */ ++ if (cache != null) { ++ block_a = new Block.BlockStatePairKey(state, fromState, face); ++ Boolean flag = cache.getValue(block_a); ++ if (flag != null) { ++ return flag; ++ } ++ } else { ++ block_a = null; ++ } + + VoxelShape voxelshape = state.getCollisionShape(world, pos); + VoxelShape voxelshape1 = fromState.getCollisionShape(world, fromPos); + boolean flag = !Shapes.mergedFaceOccludes(voxelshape, voxelshape1, face); + ++ /* + if (object2bytelinkedopenhashmap != null) { + if (object2bytelinkedopenhashmap.size() == 200) { + object2bytelinkedopenhashmap.removeLastByte(); +@@ -284,6 +314,11 @@ public abstract class FlowingFluid extends Fluid { + + object2bytelinkedopenhashmap.putAndMoveToFirst(block_a, (byte) (flag ? 1 : 0)); + } ++ */ ++ if (cache != null) { ++ cache.putValue(block_a, flag); ++ } ++ // Pufferfish end + + return flag; + } diff --git a/patches/server/0020-Pufferfish-Optimize-suffocation.patch b/patches/server/0021-Pufferfish-Optimize-suffocation.patch similarity index 100% rename from patches/server/0020-Pufferfish-Optimize-suffocation.patch rename to patches/server/0021-Pufferfish-Optimize-suffocation.patch diff --git a/patches/server/0021-Pufferfish-Early-return-optimization-for-target-find.patch b/patches/server/0022-Pufferfish-Early-return-optimization-for-target-find.patch similarity index 100% rename from patches/server/0021-Pufferfish-Early-return-optimization-for-target-find.patch rename to patches/server/0022-Pufferfish-Early-return-optimization-for-target-find.patch diff --git a/patches/server/0022-Pufferfish-Reduce-chunk-loading-lookups.patch b/patches/server/0023-Pufferfish-Reduce-chunk-loading-lookups.patch similarity index 100% rename from patches/server/0022-Pufferfish-Reduce-chunk-loading-lookups.patch rename to patches/server/0023-Pufferfish-Reduce-chunk-loading-lookups.patch diff --git a/patches/server/0023-Pufferfish-Improve-container-checking-with-a-bitset.patch b/patches/server/0024-Pufferfish-Improve-container-checking-with-a-bitset.patch similarity index 100% rename from patches/server/0023-Pufferfish-Improve-container-checking-with-a-bitset.patch rename to patches/server/0024-Pufferfish-Improve-container-checking-with-a-bitset.patch diff --git a/patches/server/0024-Pufferfish-Fix-Paper-6045-block-goal-shouldn-t-load-.patch b/patches/server/0025-Pufferfish-Fix-Paper-6045-block-goal-shouldn-t-load-.patch similarity index 100% rename from patches/server/0024-Pufferfish-Fix-Paper-6045-block-goal-shouldn-t-load-.patch rename to patches/server/0025-Pufferfish-Fix-Paper-6045-block-goal-shouldn-t-load-.patch diff --git a/patches/server/0025-Pufferfish-Reduce-entity-fluid-lookups-if-no-fluids.patch b/patches/server/0026-Pufferfish-Reduce-entity-fluid-lookups-if-no-fluids.patch similarity index 100% rename from patches/server/0025-Pufferfish-Reduce-entity-fluid-lookups-if-no-fluids.patch rename to patches/server/0026-Pufferfish-Reduce-entity-fluid-lookups-if-no-fluids.patch diff --git a/patches/server/0026-Pufferfish-Only-check-for-spooky-season-once-an-hour.patch b/patches/server/0027-Pufferfish-Only-check-for-spooky-season-once-an-hour.patch similarity index 100% rename from patches/server/0026-Pufferfish-Only-check-for-spooky-season-once-an-hour.patch rename to patches/server/0027-Pufferfish-Only-check-for-spooky-season-once-an-hour.patch diff --git a/patches/server/0027-Pufferfish-Entity-TTL.patch b/patches/server/0028-Pufferfish-Entity-TTL.patch similarity index 100% rename from patches/server/0027-Pufferfish-Entity-TTL.patch rename to patches/server/0028-Pufferfish-Entity-TTL.patch diff --git a/patches/server/0028-Pufferfish-Reduce-projectile-chunk-loading.patch b/patches/server/0029-Pufferfish-Reduce-projectile-chunk-loading.patch similarity index 100% rename from patches/server/0028-Pufferfish-Reduce-projectile-chunk-loading.patch rename to patches/server/0029-Pufferfish-Reduce-projectile-chunk-loading.patch diff --git a/patches/server/0029-Pufferfish-Dynamic-Activation-of-Brain.patch b/patches/server/0030-Pufferfish-Dynamic-Activation-of-Brain.patch similarity index 100% rename from patches/server/0029-Pufferfish-Dynamic-Activation-of-Brain.patch rename to patches/server/0030-Pufferfish-Dynamic-Activation-of-Brain.patch diff --git a/patches/server/0030-Gale-Variable-entity-wake-up-duration.patch b/patches/server/0031-Gale-Variable-entity-wake-up-duration.patch similarity index 100% rename from patches/server/0030-Gale-Variable-entity-wake-up-duration.patch rename to patches/server/0031-Gale-Variable-entity-wake-up-duration.patch diff --git a/patches/server/0031-Gale-Don-t-load-chunks-to-activate-climbing-entities.patch b/patches/server/0032-Gale-Don-t-load-chunks-to-activate-climbing-entities.patch similarity index 100% rename from patches/server/0031-Gale-Don-t-load-chunks-to-activate-climbing-entities.patch rename to patches/server/0032-Gale-Don-t-load-chunks-to-activate-climbing-entities.patch diff --git a/patches/server/0032-Gale-Optimize-sun-burn-tick.patch b/patches/server/0033-Gale-Optimize-sun-burn-tick.patch similarity index 100% rename from patches/server/0032-Gale-Optimize-sun-burn-tick.patch rename to patches/server/0033-Gale-Optimize-sun-burn-tick.patch diff --git a/patches/server/0033-Gale-Reduce-acquire-POI-for-stuck-entities.patch b/patches/server/0034-Gale-Reduce-acquire-POI-for-stuck-entities.patch similarity index 100% rename from patches/server/0033-Gale-Reduce-acquire-POI-for-stuck-entities.patch rename to patches/server/0034-Gale-Reduce-acquire-POI-for-stuck-entities.patch diff --git a/patches/server/0034-Gale-Skip-secondary-POI-sensor-if-absent.patch b/patches/server/0035-Gale-Skip-secondary-POI-sensor-if-absent.patch similarity index 100% rename from patches/server/0034-Gale-Skip-secondary-POI-sensor-if-absent.patch rename to patches/server/0035-Gale-Skip-secondary-POI-sensor-if-absent.patch diff --git a/patches/server/0035-Kaiiju-Vanilla-end-portal-teleportation.patch b/patches/server/0036-Kaiiju-Vanilla-end-portal-teleportation.patch similarity index 100% rename from patches/server/0035-Kaiiju-Vanilla-end-portal-teleportation.patch rename to patches/server/0036-Kaiiju-Vanilla-end-portal-teleportation.patch diff --git a/patches/server/0036-Try-fixing-folia-spector-teleportation.patch b/patches/server/0037-Try-fixing-folia-spector-teleportation.patch similarity index 100% rename from patches/server/0036-Try-fixing-folia-spector-teleportation.patch rename to patches/server/0037-Try-fixing-folia-spector-teleportation.patch diff --git a/patches/server/0037-Add-config-for-offline-mod-warning.patch b/patches/server/0038-Add-config-for-offline-mod-warning.patch similarity index 100% rename from patches/server/0037-Add-config-for-offline-mod-warning.patch rename to patches/server/0038-Add-config-for-offline-mod-warning.patch diff --git a/patches/server/0038-Add-config-for-root-user-warning.patch b/patches/server/0039-Add-config-for-root-user-warning.patch similarity index 100% rename from patches/server/0038-Add-config-for-root-user-warning.patch rename to patches/server/0039-Add-config-for-root-user-warning.patch