Reduce ticket operations in nether portal searching
This commit is contained in:
+43
@@ -0,0 +1,43 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: NanaChiyo0721 <nanachiyo0721@163.com>
|
||||||
|
Date: Thu, 30 Jul 2026 21:16:31 +0800
|
||||||
|
Subject: [PATCH] Reduce ticket operations in nether portal searching
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
|
index d25b1c7d1347b2731cd12cdcea7190276913de49..878a00bb28223b2719b4ce7c5d715e0346364770 100644
|
||||||
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
|
@@ -221,6 +221,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
|
private final StructureCheck structureCheck;
|
||||||
|
public final boolean tickTime; // Folia - region threading
|
||||||
|
private final LevelDebugSynchronizers debugSynchronizers = new LevelDebugSynchronizers(this);
|
||||||
|
+ public final io.nanachiyo0721.shiroha.utils.ReferenceCountingChunkLoader portalSearchingChunkLoader = new io.nanachiyo0721.shiroha.utils.ReferenceCountingChunkLoader(this, net.minecraft.world.level.chunk.status.ChunkStatus.EMPTY); // Shiroha - Reduce ticket operations in nether portal searching
|
||||||
|
|
||||||
|
// CraftBukkit start
|
||||||
|
private final ResourceKey<LevelStem> typeKey;
|
||||||
|
@@ -965,6 +966,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
|
|
||||||
|
this.debugSynchronizers.tick(this.server.debugSubscribers());
|
||||||
|
profiler.pop();
|
||||||
|
+ this.portalSearchingChunkLoader.tickChunkReferenceTTL(); // Shiroha - Reduce ticket operations in nether portal searching
|
||||||
|
}
|
||||||
|
|
||||||
|
// Folia start - region threading
|
||||||
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
|
index 63c1d223d9fc16b4211e992bde3c9f08d3ed15ca..292b062f55b7f37346750ed3a59ed4fb64c92df8 100644
|
||||||
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
|
@@ -4742,10 +4742,10 @@ public abstract class Entity
|
||||||
|
);
|
||||||
|
|
||||||
|
// kick off search for existing portal or creation
|
||||||
|
- destination.moonrise$loadChunksAsync(
|
||||||
|
+ destination.portalSearchingChunkLoader.loadChunksAsync( // Shiroha - Reduce ticket operations in nether portal searching
|
||||||
|
// add 32 so that the final search for a portal frame doesn't load any chunks
|
||||||
|
targetPos, portalSearchRadius + 32,
|
||||||
|
- net.minecraft.world.level.chunk.status.ChunkStatus.EMPTY,
|
||||||
|
+ //net.minecraft.world.level.chunk.status.ChunkStatus.EMPTY, // Shiroha - Reduce ticket operations in nether portal searching
|
||||||
|
ca.spottedleaf.concurrentutil.util.Priority.HIGH,
|
||||||
|
(chunks) -> {
|
||||||
|
BlockUtil.FoundRectangle portal =
|
||||||
+4
-4
@@ -20,10 +20,10 @@ index 3333fc2a564531ece613ed2ac77db99c59ec7390..df9a8fba86b61d2d2f82e40e0f317cab
|
|||||||
// block ticking
|
// block ticking
|
||||||
private final ObjectLinkedOpenHashSet<BlockEventData> blockEvents = new ObjectLinkedOpenHashSet<>();
|
private final ObjectLinkedOpenHashSet<BlockEventData> blockEvents = new ObjectLinkedOpenHashSet<>();
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
index d25b1c7d1347b2731cd12cdcea7190276913de49..5668f80c2ac1fcf2ac0e1e5378c789d7fce655f3 100644
|
index 878a00bb28223b2719b4ce7c5d715e0346364770..e89d2af26ffe83e71cfb733cfdbec542f845f4e5 100644
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -911,6 +911,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
@@ -912,6 +912,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
}
|
}
|
||||||
|
|
||||||
foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ACTIVATE_ENTITIES); try { // Folia - profiler
|
foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ACTIVATE_ENTITIES); try { // Folia - profiler
|
||||||
@@ -31,7 +31,7 @@ index d25b1c7d1347b2731cd12cdcea7190276913de49..5668f80c2ac1fcf2ac0e1e5378c789d7
|
|||||||
io.papermc.paper.entity.activation.ActivationRange.activateEntities(this); // Paper - EAR
|
io.papermc.paper.entity.activation.ActivationRange.activateEntities(this); // Paper - EAR
|
||||||
} finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ACTIVATE_ENTITIES); } // Folia - profiler
|
} finally { foliaProfiler.stopTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ACTIVATE_ENTITIES); } // Folia - profiler
|
||||||
foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_TICK); try { // Folia - profiler
|
foliaProfiler.startTimer(ca.spottedleaf.leafprofiler.LProfilerRegistry.ENTITY_TICK); try { // Folia - profiler
|
||||||
@@ -932,6 +933,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
@@ -933,6 +934,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
|
|
||||||
entity.stopRiding();
|
entity.stopRiding();
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@ index d25b1c7d1347b2731cd12cdcea7190276913de49..5668f80c2ac1fcf2ac0e1e5378c789d7
|
|||||||
|
|
||||||
profiler.push("tick");
|
profiler.push("tick");
|
||||||
this.guardEntityTick(this::tickNonPassenger, entity);
|
this.guardEntityTick(this::tickNonPassenger, entity);
|
||||||
@@ -941,6 +949,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
@@ -942,6 +950,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
+1
-1
@@ -8,7 +8,7 @@ As part of: Kaiiju (https://github.com/KaiijuMC/Kaiiju/blob/c2b7aec8f7b418a39a2e
|
|||||||
Licensed under: GPL-3.0 (https://github.com/KaiijuMC/Kaiiju/blob/c2b7aec8f7b418a39a2ec408e6411e6f752379da/LICENSE)
|
Licensed under: GPL-3.0 (https://github.com/KaiijuMC/Kaiiju/blob/c2b7aec8f7b418a39a2ec408e6411e6f752379da/LICENSE)
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
index 63c1d223d9fc16b4211e992bde3c9f08d3ed15ca..dda97d7e3d3a997ae4a2b6ee1656c165d5f349c4 100644
|
index 292b062f55b7f37346750ed3a59ed4fb64c92df8..06fa367e6ea5411bbb433153323867969de0156e 100644
|
||||||
--- a/net/minecraft/world/entity/Entity.java
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
+++ b/net/minecraft/world/entity/Entity.java
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
@@ -4640,15 +4640,19 @@ public abstract class Entity
|
@@ -4640,15 +4640,19 @@ public abstract class Entity
|
||||||
+3
-3
@@ -93,10 +93,10 @@ index 3ecedf303384c172a5e2a19c9e6ac0c3a43cef74..ee7fce1e4e9b94b1f9c956c376fff0ab
|
|||||||
//this.isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked // Folia - region threading
|
//this.isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked // Folia - region threading
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
index 5668f80c2ac1fcf2ac0e1e5378c789d7fce655f3..ecb1b98723e78e9d2f3ce182be8f78f8f32a52da 100644
|
index e89d2af26ffe83e71cfb733cfdbec542f845f4e5..1505a920694068260d9d81bc4f3c96f3a154f19d 100644
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -1536,8 +1536,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
@@ -1538,8 +1538,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
// removed from region while ticking
|
// removed from region while ticking
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -112,7 +112,7 @@ index 5668f80c2ac1fcf2ac0e1e5378c789d7fce655f3..ecb1b98723e78e9d2f3ce182be8f78f8
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1581,8 +1588,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
@@ -1583,8 +1590,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
// removed from region while ticking
|
// removed from region while ticking
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
+6
-6
@@ -68,10 +68,10 @@ index ee7fce1e4e9b94b1f9c956c376fff0abee51b0ca..87099cabe804741e6dc278bccdfa79b0
|
|||||||
this.lastServerStatus = nano;
|
this.lastServerStatus = nano;
|
||||||
this.status = this.buildServerStatus();
|
this.status = this.buildServerStatus();
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
index ecb1b98723e78e9d2f3ce182be8f78f8f32a52da..ce0dca54b551c67797e197f848334f34e1fb3da7 100644
|
index 1505a920694068260d9d81bc4f3c96f3a154f19d..52d74e9df3a01163014ae50ce4f49eba6639ec63 100644
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -1485,6 +1485,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
@@ -1487,6 +1487,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
public void tickNonPassenger(final Entity entity) {
|
public void tickNonPassenger(final Entity entity) {
|
||||||
// Paper start - log detailed entity tick information
|
// Paper start - log detailed entity tick information
|
||||||
ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot tick an entity off-main");
|
ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot tick an entity off-main");
|
||||||
@@ -80,7 +80,7 @@ index ecb1b98723e78e9d2f3ce182be8f78f8f32a52da..ce0dca54b551c67797e197f848334f34
|
|||||||
try {
|
try {
|
||||||
// Folia - region threading
|
// Folia - region threading
|
||||||
// Paper end - log detailed entity tick information
|
// Paper end - log detailed entity tick information
|
||||||
@@ -1561,6 +1563,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
@@ -1563,6 +1565,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
} finally {
|
} finally {
|
||||||
// Folia - region threading
|
// Folia - region threading
|
||||||
}
|
}
|
||||||
@@ -88,7 +88,7 @@ index ecb1b98723e78e9d2f3ce182be8f78f8f32a52da..ce0dca54b551c67797e197f848334f34
|
|||||||
// Paper end - log detailed entity tick information
|
// Paper end - log detailed entity tick information
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1572,6 +1575,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
@@ -1574,6 +1577,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
final int timerId = isActive ? entity.getType().tickTimerId : entity.getType().inactiveTickTimerId;
|
final int timerId = isActive ? entity.getType().tickTimerId : entity.getType().inactiveTickTimerId;
|
||||||
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler();
|
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler();
|
||||||
foliaProfiler.startTimer(timerId);
|
foliaProfiler.startTimer(timerId);
|
||||||
@@ -97,7 +97,7 @@ index ecb1b98723e78e9d2f3ce182be8f78f8f32a52da..ce0dca54b551c67797e197f848334f34
|
|||||||
try {
|
try {
|
||||||
// Folia end - profiler
|
// Folia end - profiler
|
||||||
entity.setOldPosAndRot();
|
entity.setOldPosAndRot();
|
||||||
@@ -1613,6 +1618,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
@@ -1615,6 +1620,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
this.tickPassenger(entity, passenger, isActive); // Paper - EAR 2
|
this.tickPassenger(entity, passenger, isActive); // Paper - EAR 2
|
||||||
}
|
}
|
||||||
} finally { foliaProfiler.stopTimer(timerId); } // Folia - profiler
|
} finally { foliaProfiler.stopTimer(timerId); } // Folia - profiler
|
||||||
@@ -171,7 +171,7 @@ index f03fa06c0ba56f7f5e1e45bc1568a490751efde3..eee1c14249addbf4714df733870da974
|
|||||||
+ // KioCG end
|
+ // KioCG end
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
index dda97d7e3d3a997ae4a2b6ee1656c165d5f349c4..3f3110efa6a917f5ad3892a57229a8ae937cd023 100644
|
index 06fa367e6ea5411bbb433153323867969de0156e..fb0fe5631e8fd5d1053e31e4f121601a64647f1b 100644
|
||||||
--- a/net/minecraft/world/entity/Entity.java
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
+++ b/net/minecraft/world/entity/Entity.java
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
@@ -6432,4 +6432,6 @@ public abstract class Entity
|
@@ -6432,4 +6432,6 @@ public abstract class Entity
|
||||||
+1
-1
@@ -240,7 +240,7 @@ index 6e08d50794c4af4405f3e164a3fd46f376b3f78f..dd2d0940eece3e85078e574f66f71a4c
|
|||||||
|
|
||||||
int getContainerSize();
|
int getContainerSize();
|
||||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
index 3f3110efa6a917f5ad3892a57229a8ae937cd023..34daca8ff9cbd03458ac864ed3d31f6603301864 100644
|
index fb0fe5631e8fd5d1053e31e4f121601a64647f1b..6b736388138ff58daeffae6ada470b9045fd51b6 100644
|
||||||
--- a/net/minecraft/world/entity/Entity.java
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
+++ b/net/minecraft/world/entity/Entity.java
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
@@ -324,7 +324,7 @@ public abstract class Entity
|
@@ -324,7 +324,7 @@ public abstract class Entity
|
||||||
+2
-2
@@ -63,10 +63,10 @@ index 7927769cf9bccb892745f4d1390eb83b2861d1bb..414c21345879f589fb61130180d0ca60
|
|||||||
}
|
}
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
index ce0dca54b551c67797e197f848334f34e1fb3da7..8634e0b6d280e2c5900197420ad457f778245087 100644
|
index 52d74e9df3a01163014ae50ce4f49eba6639ec63..8c2d6a43b52ae6e70506bb779a9dfd33a7a1d440 100644
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -633,6 +633,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
@@ -634,6 +634,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
generator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, generator, gen);
|
generator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, generator, gen);
|
||||||
}
|
}
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
+1
-1
@@ -10,7 +10,7 @@ VMP (https://github.com/RelativityMC/VMP-fabric)
|
|||||||
Licensed under: MIT (https://opensource.org/licenses/MIT)
|
Licensed under: MIT (https://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
index 34daca8ff9cbd03458ac864ed3d31f6603301864..e7497f8f488cf9833b428ce1c82451c902465d19 100644
|
index 6b736388138ff58daeffae6ada470b9045fd51b6..fcca07953fb91d5b1b7230682b657ea289d779b7 100644
|
||||||
--- a/net/minecraft/world/entity/Entity.java
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
+++ b/net/minecraft/world/entity/Entity.java
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
@@ -1152,8 +1152,14 @@ public abstract class Entity
|
@@ -1152,8 +1152,14 @@ public abstract class Entity
|
||||||
+3
-3
@@ -57,10 +57,10 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||||
index 8634e0b6d280e2c5900197420ad457f778245087..05aa5cd8869d4997da137661dcdc9f2f61c6e438 100644
|
index 8c2d6a43b52ae6e70506bb779a9dfd33a7a1d440..5506018ee75eaf13d072969699a41566cf054cf5 100644
|
||||||
--- a/net/minecraft/server/level/ServerLevel.java
|
--- a/net/minecraft/server/level/ServerLevel.java
|
||||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||||
@@ -1052,7 +1052,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
@@ -1054,7 +1054,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paper start - optimise random ticking
|
// Paper start - optimise random ticking
|
||||||
@@ -69,7 +69,7 @@ index 8634e0b6d280e2c5900197420ad457f778245087..05aa5cd8869d4997da137661dcdc9f2f
|
|||||||
|
|
||||||
private void optimiseRandomTick(final LevelChunk chunk, final int tickSpeed) {
|
private void optimiseRandomTick(final LevelChunk chunk, final int tickSpeed) {
|
||||||
final LevelChunkSection[] sections = chunk.getSections();
|
final LevelChunkSection[] sections = chunk.getSections();
|
||||||
@@ -1134,7 +1134,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
@@ -1136,7 +1136,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
|
||||||
int minZ = chunkPos.getMinBlockZ();
|
int minZ = chunkPos.getMinBlockZ();
|
||||||
ProfilerFiller profiler = Profiler.get();
|
ProfilerFiller profiler = Profiler.get();
|
||||||
profiler.push("thunder");
|
profiler.push("thunder");
|
||||||
+1
-1
@@ -20,7 +20,7 @@ As part of: Akarin (https://github.com/Akarin-project/Akarin)
|
|||||||
Licensed under: GPL-3.0-only (https://www.gnu.org/licenses/gpl-3.0.html)
|
Licensed under: GPL-3.0-only (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
index e7497f8f488cf9833b428ce1c82451c902465d19..3c055fa3f6641137dda1532a19af8b67caa52143 100644
|
index fcca07953fb91d5b1b7230682b657ea289d779b7..e4dfb9dec23b1ac38e2f2de529d9683615e758a7 100644
|
||||||
--- a/net/minecraft/world/entity/Entity.java
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
+++ b/net/minecraft/world/entity/Entity.java
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
@@ -2438,8 +2438,8 @@ public abstract class Entity
|
@@ -2438,8 +2438,8 @@ public abstract class Entity
|
||||||
+1
-1
@@ -7,7 +7,7 @@ License: GPL-3.0-only (https://www.gnu.org/licenses/gpl-3.0.html)
|
|||||||
Gale - https://github.com/GaleMC/Gale
|
Gale - https://github.com/GaleMC/Gale
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
index 3c055fa3f6641137dda1532a19af8b67caa52143..503af0546705e88ec06e064ec1c24f87cb25abeb 100644
|
index e4dfb9dec23b1ac38e2f2de529d9683615e758a7..ab3bc9fea3fb5da4f851f4722fae77dd961f2e55 100644
|
||||||
--- a/net/minecraft/world/entity/Entity.java
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
+++ b/net/minecraft/world/entity/Entity.java
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
@@ -1299,8 +1299,17 @@ public abstract class Entity
|
@@ -1299,8 +1299,17 @@ public abstract class Entity
|
||||||
+312
@@ -0,0 +1,312 @@
|
|||||||
|
package io.nanachiyo0721.shiroha.utils;
|
||||||
|
|
||||||
|
import ca.spottedleaf.concurrentutil.completable.CallbackCompletable;
|
||||||
|
import ca.spottedleaf.concurrentutil.map.concurrent.longs.ConcurrentChainedLong2ReferenceHashTable;
|
||||||
|
import ca.spottedleaf.concurrentutil.util.Priority;
|
||||||
|
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
||||||
|
import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler;
|
||||||
|
import io.papermc.paper.threadedregions.RegionizedServer;
|
||||||
|
import io.papermc.paper.threadedregions.ThreadedRegionizer;
|
||||||
|
import io.papermc.paper.threadedregions.TickRegions;
|
||||||
|
import it.unimi.dsi.fastutil.Pair;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一个简单的基于folia的RegionizedTaskQueue引用计数的轻量ticket区块加载器
|
||||||
|
* 用于在folia传送门搜索的高频率scheduleChunkLoad的调用下减少ticket操作从而减轻锁负载
|
||||||
|
* 大部分内容物均取自folia的RegionizedTaskQueue(引用计数), ttl机制取自我的优化)
|
||||||
|
*
|
||||||
|
* @see io.papermc.paper.threadedregions.RegionizedTaskQueue
|
||||||
|
* @see net.minecraft.world.entity.Entity#findOrCreatePortalAsync(ServerLevel, BlockPos, ServerLevel, Entity.PortalType, CallbackCompletable)
|
||||||
|
*/
|
||||||
|
public class ReferenceCountingChunkLoader {
|
||||||
|
private static final long MAX_CHUNK_TTL_TICKS = 2L;
|
||||||
|
|
||||||
|
private final ServerLevel world;
|
||||||
|
private final ChunkStatus targetStatus;
|
||||||
|
private final ConcurrentChainedLong2ReferenceHashTable<ReferenceCountData> referenceCounters = new ConcurrentChainedLong2ReferenceHashTable<>();
|
||||||
|
|
||||||
|
public ReferenceCountingChunkLoader(ServerLevel world, ChunkStatus targetStatus) {
|
||||||
|
this.world = world;
|
||||||
|
this.targetStatus = targetStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void decrementReference(final @NonNull ReferenceCountData referenceCountData, final long coord) {
|
||||||
|
if (!referenceCountData.decreaseReferenceCount()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ReferenceCountData[] toRemoveTicket = new ReferenceCountData[1];
|
||||||
|
|
||||||
|
this.referenceCounters.computeIfPresent(coord, (final long keyInMap, final ReferenceCountData valueInMap) -> {
|
||||||
|
if (valueInMap.referenceCount.get() != 0L) {
|
||||||
|
return valueInMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
toRemoveTicket[0] = valueInMap;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (toRemoveTicket[0] != null) {
|
||||||
|
this.removeTicket(coord, toRemoveTicket[0].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeTicket(final long coord, final long id) {
|
||||||
|
this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.removeTicketAtLevel(
|
||||||
|
ChunkTaskScheduler.CHUNK_LOAD, coord, ChunkTaskScheduler.getTicketLevel(this.targetStatus), Long.valueOf(id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addTicket(final long coord, final long id) {
|
||||||
|
this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.addTicketAtLevel(
|
||||||
|
ChunkTaskScheduler.CHUNK_LOAD, coord, ChunkTaskScheduler.getTicketLevel(this.targetStatus), Long.valueOf(id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processTicketUpdates(final long coord) {
|
||||||
|
this.world.moonrise$getChunkTaskScheduler().chunkHolderManager.processTicketUpdates(CoordinateUtils.getChunkX(coord), CoordinateUtils.getChunkZ(coord));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureTicketAdded(final long coord, final @NonNull ReferenceCountData referenceCountData) {
|
||||||
|
if (!referenceCountData.addedTicket) {
|
||||||
|
this.addTicket(coord, referenceCountData.id);
|
||||||
|
this.processTicketUpdates(coord);
|
||||||
|
referenceCountData.addedTicket = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void loadChunksAsync(final @NonNull BlockPos pos, final int radiusBlocks,
|
||||||
|
final Priority priority,
|
||||||
|
final Consumer<List<ChunkAccess>> onLoad) {
|
||||||
|
this.loadChunksAsync(
|
||||||
|
(pos.getX() - radiusBlocks) >> 4,
|
||||||
|
(pos.getX() + radiusBlocks) >> 4,
|
||||||
|
(pos.getZ() - radiusBlocks) >> 4,
|
||||||
|
(pos.getZ() + radiusBlocks) >> 4,
|
||||||
|
priority, onLoad
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void loadChunksAsync(final int minChunkX, final int maxChunkX, final int minChunkZ, final int maxChunkZ,
|
||||||
|
final Priority priority,
|
||||||
|
final Consumer<java.util.List<ChunkAccess>> onLoad) {
|
||||||
|
this.loadChunksAsync(minChunkX, maxChunkX, minChunkZ, maxChunkZ, priority, onLoad, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final void loadChunksAsync(final int minChunkX, final int maxChunkX, final int minChunkZ, final int maxChunkZ,
|
||||||
|
final Priority priority,
|
||||||
|
final Consumer<List<ChunkAccess>> onLoad, final Consumer<ChunkAccess> onEachLoad) {
|
||||||
|
final int requiredChunks = (maxChunkX - minChunkX + 1) * (maxChunkZ - minChunkZ + 1);
|
||||||
|
final AtomicInteger loadedChunks = new AtomicInteger();
|
||||||
|
|
||||||
|
final List<Pair<ReferenceCountData, ChunkAccess>> ret = new ArrayList<>(requiredChunks);
|
||||||
|
|
||||||
|
final Consumer<ChunkAccess> consumer = (final ChunkAccess chunk) -> {
|
||||||
|
|
||||||
|
if (chunk != null) {
|
||||||
|
final long pos = chunk.getPos().longKey();
|
||||||
|
|
||||||
|
synchronized (ret) {
|
||||||
|
ret.add(Pair.of(this.incrementReference(pos), chunk));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onEachLoad != null) {
|
||||||
|
onEachLoad.accept(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadedChunks.incrementAndGet() == requiredChunks) {
|
||||||
|
try {
|
||||||
|
if (onLoad != null) {
|
||||||
|
final List<ChunkAccess> processed = new ArrayList<>(ret.size());
|
||||||
|
|
||||||
|
for (Pair<ReferenceCountData, ChunkAccess> result : ret) {
|
||||||
|
processed.add(result.right());
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad.accept(processed);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
for (Pair<ReferenceCountData, ChunkAccess> extraRefEntry : ret) {
|
||||||
|
this.decrementReference(extraRefEntry.left(), extraRefEntry.right().getPos().longKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int cx = minChunkX; cx <= maxChunkX; ++cx) {
|
||||||
|
for (int cz = minChunkZ; cz <= maxChunkZ; ++cz) {
|
||||||
|
this.loadAsync(cx, cz, consumer, priority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadAsync(int chunkX, int chunkZ, Consumer<ChunkAccess> callback, Priority priority) {
|
||||||
|
final long coord = CoordinateUtils.getChunkKey(chunkX, chunkZ);
|
||||||
|
final ReferenceCountData increased = this.incrementReference(coord);
|
||||||
|
|
||||||
|
final ChunkAccess cached = increased.cached;
|
||||||
|
if (cached != null) {
|
||||||
|
RegionizedServer.getInstance().taskQueue.queueChunkTask(this.world, chunkX, chunkZ, () -> {
|
||||||
|
try {
|
||||||
|
callback.accept(cached);
|
||||||
|
}finally {
|
||||||
|
this.decrementReference(increased, coord);
|
||||||
|
}
|
||||||
|
}, priority);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.world.moonrise$getChunkTaskScheduler().scheduleChunkLoad(
|
||||||
|
chunkX, chunkZ, this.targetStatus, true, priority,
|
||||||
|
chunk -> {
|
||||||
|
try {
|
||||||
|
increased.cached = chunk;
|
||||||
|
|
||||||
|
callback.accept(chunk);
|
||||||
|
}finally {
|
||||||
|
this.decrementReference(increased, coord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ReferenceCountData incrementReference(final long coord) {
|
||||||
|
ReferenceCountData referenceCountData = this.referenceCounters.get(coord);
|
||||||
|
|
||||||
|
if (referenceCountData != null && referenceCountData.addCount()) {
|
||||||
|
this.ensureTicketAdded(coord, referenceCountData);
|
||||||
|
return referenceCountData;
|
||||||
|
}
|
||||||
|
|
||||||
|
referenceCountData = this.referenceCounters.compute(coord, (final long keyInMap, final ReferenceCountData valueInMap) -> {
|
||||||
|
if (valueInMap == null) {
|
||||||
|
return new ReferenceCountData();
|
||||||
|
}
|
||||||
|
|
||||||
|
valueInMap.referenceCount.getAndIncrement();
|
||||||
|
|
||||||
|
return valueInMap;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.ensureTicketAdded(coord, referenceCountData);
|
||||||
|
|
||||||
|
return referenceCountData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tickChunkReferenceTTL() {
|
||||||
|
final ThreadedRegionizer.ThreadedRegion<TickRegions.TickRegionData, TickRegions.TickRegionSectionData> currentRegion
|
||||||
|
= io.papermc.paper.threadedregions.TickRegionScheduler.getCurrentRegion();
|
||||||
|
if (currentRegion == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ReferenceCountData[] toRemoveTicket = new ReferenceCountData[1];
|
||||||
|
|
||||||
|
for (ConcurrentChainedLong2ReferenceHashTable.TableEntry<ReferenceCountData> counterEntry : this.referenceCounters.entrySet()) {
|
||||||
|
final long coord = counterEntry.getKey();
|
||||||
|
final ReferenceCountData counterData = counterEntry.getValue();
|
||||||
|
|
||||||
|
if (currentRegion == this.world.regioniser.getRegionAtUnsynchronised(CoordinateUtils.getChunkX(coord), CoordinateUtils.getChunkZ(coord))) {
|
||||||
|
long curr = counterData.referenceTTL.get();
|
||||||
|
if (curr == (curr = counterData.referenceTTL.compareAndExchange(curr, curr - 1))) {
|
||||||
|
if (counterData.referenceCount.get() != 0L) {
|
||||||
|
counterData.referenceTTL.set(MAX_CHUNK_TTL_TICKS);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curr <= 0) {
|
||||||
|
this.referenceCounters.computeIfPresent(coord, (final long keyInMap, final ReferenceCountData valueInMap) -> {
|
||||||
|
if (valueInMap.referenceCount.get() != 0L) {
|
||||||
|
valueInMap.referenceTTL.set(MAX_CHUNK_TTL_TICKS);
|
||||||
|
return valueInMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
toRemoveTicket[0] = valueInMap;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (toRemoveTicket[0] != null) {
|
||||||
|
this.removeTicket(coord, toRemoveTicket[0].id);
|
||||||
|
toRemoveTicket[0] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class ReferenceCountData {
|
||||||
|
|
||||||
|
private static final AtomicLong ID_GENERATOR = new AtomicLong();
|
||||||
|
|
||||||
|
private final long id = ID_GENERATOR.getAndIncrement();
|
||||||
|
|
||||||
|
public final AtomicLong referenceCount = new AtomicLong(1L);
|
||||||
|
public final AtomicLong referenceTTL = new AtomicLong(MAX_CHUNK_TTL_TICKS);
|
||||||
|
|
||||||
|
public volatile ChunkAccess cached;
|
||||||
|
public volatile boolean addedTicket;
|
||||||
|
|
||||||
|
public boolean addCount() {
|
||||||
|
int failures = 0;
|
||||||
|
for (long curr = this.referenceCount.get();;) {
|
||||||
|
for (int i = 0; i < failures; ++i) {
|
||||||
|
Thread.onSpinWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curr == 0L) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curr == (curr = this.referenceCount.compareAndExchange(curr, curr + 1L))) {
|
||||||
|
int ttlFailures = 0;
|
||||||
|
for (long currTTL = this.referenceTTL.get();;) {
|
||||||
|
for (int i = 0; i < ttlFailures; i++) {
|
||||||
|
Thread.onSpinWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currTTL <= 0) {
|
||||||
|
this.referenceCount.decrementAndGet();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currTTL == (currTTL = this.referenceTTL.compareAndExchange(currTTL, MAX_CHUNK_TTL_TICKS))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++ttlFailures;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
++failures;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean decreaseReferenceCount() {
|
||||||
|
final long res = this.referenceCount.decrementAndGet();
|
||||||
|
if (res >= 0L) {
|
||||||
|
return res == 0L && this.referenceTTL.get() <= 0L;
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Negative reference count");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user