mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2026-01-04 15:41:40 +00:00
use TrackedChunk from ChunkData to prevent hash lookup (#461)
closes #441
This commit is contained in:
@@ -28,28 +28,10 @@ However we still recommend to use those packet based NPC plugins,
|
||||
e.g. ZNPC Plus, Adyeshach, Fancy NPC, etc.
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
|
||||
index 1b8193587814225c2ef2c5d9e667436eb50ff6c5..2a2626e90836ae52a8a686b2040843c6644b6914 100644
|
||||
index 1b8193587814225c2ef2c5d9e667436eb50ff6c5..356ec20eff799aa12ed6b4f9e54e8721c50a0068 100644
|
||||
--- a/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
|
||||
+++ b/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
|
||||
@@ -60,7 +60,16 @@ public final class NearbyPlayers {
|
||||
|
||||
private final ServerLevel world;
|
||||
private final Reference2ReferenceOpenHashMap<ServerPlayer, TrackedPlayer[]> players = new Reference2ReferenceOpenHashMap<>();
|
||||
- private final Long2ReferenceOpenHashMap<TrackedChunk> byChunk = new Long2ReferenceOpenHashMap<>();
|
||||
+ // Leaf start - Multithreaded tracker
|
||||
+ private final it.unimi.dsi.fastutil.longs.Long2ReferenceMap<TrackedChunk> byChunk;
|
||||
+ {
|
||||
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled) {
|
||||
+ byChunk = it.unimi.dsi.fastutil.longs.Long2ReferenceMaps.synchronize(new Long2ReferenceOpenHashMap<>());
|
||||
+ } else {
|
||||
+ byChunk = new Long2ReferenceOpenHashMap<>();
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaf end - Multithreaded tracker
|
||||
private final Long2ReferenceOpenHashMap<ReferenceList<ServerPlayer>>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES];
|
||||
{
|
||||
for (int i = 0; i < this.directByChunk.length; ++i) {
|
||||
@@ -164,6 +173,8 @@ public final class NearbyPlayers {
|
||||
@@ -164,6 +164,8 @@ public final class NearbyPlayers {
|
||||
private int nonEmptyLists;
|
||||
private long updateCount;
|
||||
|
||||
@@ -58,7 +40,7 @@ index 1b8193587814225c2ef2c5d9e667436eb50ff6c5..2a2626e90836ae52a8a686b2040843c6
|
||||
public TrackedChunk(final long chunkKey, final NearbyPlayers nearbyPlayers) {
|
||||
this.chunkKey = chunkKey;
|
||||
this.nearbyPlayers = nearbyPlayers;
|
||||
@@ -177,6 +188,12 @@ public final class NearbyPlayers {
|
||||
@@ -177,6 +179,12 @@ public final class NearbyPlayers {
|
||||
return this.updateCount;
|
||||
}
|
||||
|
||||
@@ -71,7 +53,7 @@ index 1b8193587814225c2ef2c5d9e667436eb50ff6c5..2a2626e90836ae52a8a686b2040843c6
|
||||
public ReferenceList<ServerPlayer> getPlayers(final NearbyMapType type) {
|
||||
return this.players[type.ordinal()];
|
||||
}
|
||||
@@ -185,6 +202,12 @@ public final class NearbyPlayers {
|
||||
@@ -185,6 +193,12 @@ public final class NearbyPlayers {
|
||||
++this.updateCount;
|
||||
|
||||
final int idx = type.ordinal();
|
||||
@@ -84,7 +66,7 @@ index 1b8193587814225c2ef2c5d9e667436eb50ff6c5..2a2626e90836ae52a8a686b2040843c6
|
||||
final ReferenceList<ServerPlayer> list = this.players[idx];
|
||||
if (list == null) {
|
||||
++this.nonEmptyLists;
|
||||
@@ -203,6 +226,12 @@ public final class NearbyPlayers {
|
||||
@@ -203,6 +217,12 @@ public final class NearbyPlayers {
|
||||
++this.updateCount;
|
||||
|
||||
final int idx = type.ordinal();
|
||||
@@ -98,7 +80,7 @@ index 1b8193587814225c2ef2c5d9e667436eb50ff6c5..2a2626e90836ae52a8a686b2040843c6
|
||||
if (list == null) {
|
||||
throw new IllegalStateException("Does not contain player " + player);
|
||||
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
|
||||
index bdc1200ef5317fdaf58973bf580b0a672aee800f..e36086cd3c205e66ba1028343028af2239c1d93f 100644
|
||||
index bdc1200ef5317fdaf58973bf580b0a672aee800f..f34b8012d48ce1b69c1a1529d7ae46b624785ffa 100644
|
||||
--- a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
|
||||
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java
|
||||
@@ -344,7 +344,7 @@ public final class RegionizedPlayerChunkLoader {
|
||||
@@ -116,7 +98,7 @@ index bdc1200ef5317fdaf58973bf580b0a672aee800f..e36086cd3c205e66ba1028343028af22
|
||||
PlayerChunkSender.sendChunk(this.player.connection, this.world, chunk);
|
||||
+ // Leaf start - Multithreaded tracker
|
||||
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled) {
|
||||
+ ca.spottedleaf.moonrise.common.misc.NearbyPlayers.TrackedChunk trackedChunk = this.world.moonrise$getNearbyPlayers().getChunk(chunkX, chunkZ);
|
||||
+ ca.spottedleaf.moonrise.common.misc.NearbyPlayers.TrackedChunk trackedChunk = chunk.moonrise$getChunkHolder().holderData.nearbyPlayers;
|
||||
+ if (trackedChunk != null) {
|
||||
+ trackedChunk.trackingUpdateCountAtomic.getAndIncrement();
|
||||
+ }
|
||||
|
||||
@@ -9,10 +9,10 @@ This patch didn't cahce SectionPos or BlockPos to chunkKey, since they are mutab
|
||||
The JMH benchmark of this patch can be found in SunBox's `CacheChunkKey`
|
||||
|
||||
diff --git a/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
|
||||
index 2a2626e90836ae52a8a686b2040843c6644b6914..283e02b32cae0bc1b0cd71602795aa48987903db 100644
|
||||
index 356ec20eff799aa12ed6b4f9e54e8721c50a0068..499cad369242f9ad724b3251538d62d8dc8d2ec8 100644
|
||||
--- a/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
|
||||
+++ b/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
|
||||
@@ -136,7 +136,7 @@ public final class NearbyPlayers {
|
||||
@@ -127,7 +127,7 @@ public final class NearbyPlayers {
|
||||
}
|
||||
|
||||
public TrackedChunk getChunk(final ChunkPos pos) {
|
||||
@@ -21,7 +21,7 @@ index 2a2626e90836ae52a8a686b2040843c6644b6914..283e02b32cae0bc1b0cd71602795aa48
|
||||
}
|
||||
|
||||
public TrackedChunk getChunk(final BlockPos pos) {
|
||||
@@ -152,7 +152,7 @@ public final class NearbyPlayers {
|
||||
@@ -143,7 +143,7 @@ public final class NearbyPlayers {
|
||||
}
|
||||
|
||||
public ReferenceList<ServerPlayer> getPlayers(final ChunkPos pos, final NearbyMapType type) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.dreeam.leaf.async.tracker;
|
||||
|
||||
import ca.spottedleaf.moonrise.common.misc.NearbyPlayers;
|
||||
import ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity;
|
||||
import ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity;
|
||||
import io.papermc.paper.event.player.PlayerTrackEntityEvent;
|
||||
import io.papermc.paper.event.player.PlayerUntrackEntityEvent;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
@@ -119,31 +120,34 @@ public final class TrackerCtx {
|
||||
}
|
||||
|
||||
void handle(boolean flush) {
|
||||
handlePackets(world, packets, flush);
|
||||
|
||||
if (!pluginEntity.isEmpty()) {
|
||||
for (final Entity entity : pluginEntity) {
|
||||
final ChunkMap.TrackedEntity tracker = ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$getTrackedEntity();
|
||||
final ChunkMap.TrackedEntity tracker = ((EntityTrackerEntity) entity).moonrise$getTrackedEntity();
|
||||
if (tracker == null) {
|
||||
continue;
|
||||
}
|
||||
NearbyPlayers.TrackedChunk trackedChunk = world.moonrise$getNearbyPlayers().getChunk(entity.chunkPosition());
|
||||
tracker.leafTick(this, trackedChunk);
|
||||
ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData chunk = ((ChunkSystemEntity) entity).moonrise$getChunkData();
|
||||
if (chunk == null) {
|
||||
continue;
|
||||
}
|
||||
tracker.moonrise$tick(chunk.nearbyPlayers);
|
||||
boolean flag = false;
|
||||
if (tracker.moonrise$hasPlayers()) {
|
||||
flag = true;
|
||||
} else {
|
||||
FullChunkStatus status = ((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity) entity).moonrise$getChunkStatus();
|
||||
FullChunkStatus status = ((ChunkSystemEntity) entity).moonrise$getChunkStatus();
|
||||
if (status != null && status.isOrAfter(FullChunkStatus.ENTITY_TICKING)) {
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
tracker.serverEntity.leafSendChanges(this, tracker);
|
||||
tracker.serverEntity.sendChanges();
|
||||
}
|
||||
}
|
||||
pluginEntity.clear();
|
||||
}
|
||||
|
||||
handlePackets(world, packets, flush);
|
||||
if (!bukkitVelocityEvent.isEmpty()) {
|
||||
for (ServerPlayer player : bukkitVelocityEvent) {
|
||||
if (!world.equals(player.level())) {
|
||||
|
||||
@@ -1,36 +1,26 @@
|
||||
package org.dreeam.leaf.async.tracker;
|
||||
|
||||
import ca.spottedleaf.moonrise.common.misc.NearbyPlayers;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity;
|
||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
|
||||
import ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.FullChunkStatus;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import org.dreeam.leaf.util.EntitySlice;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public final class TrackerTask implements Callable<TrackerCtx> {
|
||||
public final ServerLevel world;
|
||||
private final EntitySlice entities;
|
||||
|
||||
public TrackerTask(ServerLevel world, EntitySlice trackerEntities) {
|
||||
this.world = world;
|
||||
this.entities = trackerEntities;
|
||||
}
|
||||
public record TrackerTask(ServerLevel world, EntitySlice entities) implements Callable<TrackerCtx> {
|
||||
|
||||
@Override
|
||||
public TrackerCtx call() throws Exception {
|
||||
NearbyPlayers nearbyPlayers = world.moonrise$getNearbyPlayers();
|
||||
TrackerCtx ctx = new TrackerCtx(this.world);
|
||||
final TrackerCtx ctx = new TrackerCtx(this.world);
|
||||
final Entity[] raw = entities.array();
|
||||
Long2ObjectMap<NearbyPlayers.TrackedChunk> chunkCache = new Long2ObjectOpenHashMap<>();
|
||||
for (int i = entities.start(); i < entities.end(); i++) {
|
||||
final Entity entity = raw[i];
|
||||
final ChunkMap.TrackedEntity tracker = ((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$getTrackedEntity();
|
||||
long chunkPos = entity.chunkPosition().toLong();
|
||||
final ChunkMap.TrackedEntity tracker = ((EntityTrackerEntity) entity).moonrise$getTrackedEntity();
|
||||
// removed in world if null
|
||||
if (tracker == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -38,16 +28,18 @@ public final class TrackerTask implements Callable<TrackerCtx> {
|
||||
ctx.citizensEntity(entity);
|
||||
continue;
|
||||
}
|
||||
NearbyPlayers.TrackedChunk trackedChunk = chunkCache.computeIfAbsent(chunkPos, k -> nearbyPlayers.getChunk(ChunkPos.getX(k), ChunkPos.getZ(k)));
|
||||
|
||||
tracker.leafTick(ctx, trackedChunk);
|
||||
ChunkData chunkData = ((ChunkSystemEntity) entity).moonrise$getChunkData();
|
||||
// removed in world if null
|
||||
if (chunkData == null) {
|
||||
continue;
|
||||
}
|
||||
tracker.leafTick(ctx, chunkData.nearbyPlayers);
|
||||
boolean flag = false;
|
||||
if (tracker.moonrise$hasPlayers()) {
|
||||
flag = true;
|
||||
} else {
|
||||
// may read old value
|
||||
FullChunkStatus status = ((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity) entity).moonrise$getChunkStatus();
|
||||
// removed in world
|
||||
FullChunkStatus status = ((ChunkSystemEntity) entity).moonrise$getChunkStatus();
|
||||
// removed in world if null
|
||||
if (status != null && status.isOrAfter(FullChunkStatus.ENTITY_TICKING)) {
|
||||
flag = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user