geforkt von Mirrors/Paper
More more more more more more more work
Dieser Commit ist enthalten in:
Ursprung
82f6e6bb0e
Commit
c36c2d46d3
@ -72,12 +72,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ continue;
|
+ continue;
|
||||||
+ }
|
+ }
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
Phantom entityphantom = (Phantom) EntityType.PHANTOM.create((Level) world);
|
Phantom entityphantom = (Phantom) EntityType.PHANTOM.create(world);
|
||||||
-
|
-
|
||||||
+ entityphantom.setSpawningEntity(entityhuman.getUUID()); // Paper
|
+ entityphantom.setSpawningEntity(entityhuman.getUUID()); // Paper
|
||||||
entityphantom.moveTo(blockposition1, 0.0F, 0.0F);
|
entityphantom.moveTo(blockposition1, 0.0F, 0.0F);
|
||||||
groupdataentity = entityphantom.finalizeSpawn(world, difficultydamagescaler, MobSpawnType.NATURAL, groupdataentity, (CompoundTag) null);
|
groupdataentity = entityphantom.finalizeSpawn(world, difficultydamagescaler, MobSpawnType.NATURAL, groupdataentity, (CompoundTag) null);
|
||||||
world.addAllEntities(entityphantom, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit
|
world.addFreshEntityWithPassengers(entityphantom, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit
|
||||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
@ -23,9 +23,9 @@ diff --git a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java b/sr
|
|||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
--- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||||
+++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
+++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
@@ -0,0 +0,0 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||||
import net.minecraft.world.level.material.FlowingFluid;
|
import net.minecraft.world.level.material.FlowingFluid;
|
||||||
import net.minecraft.world.level.material.Fluid;
|
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
+import net.minecraft.world.level.material.Material;
|
+import net.minecraft.world.level.material.Material;
|
||||||
import net.minecraft.world.level.pathfinder.PathComputationType;
|
import net.minecraft.world.level.pathfinder.PathComputationType;
|
||||||
@ -35,8 +35,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
@Override
|
@Override
|
||||||
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||||
if (this.shouldSpreadLiquid(world, pos, state)) {
|
if (this.shouldSpreadLiquid(world, pos, state)) {
|
||||||
- world.getLiquidTicks().scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay((LevelReader) world));
|
- world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world));
|
||||||
+ world.getLiquidTicks().scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
+ world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -64,8 +64,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
@Override
|
@Override
|
||||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean notify) {
|
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean notify) {
|
||||||
if (this.shouldSpreadLiquid(world, pos, state)) {
|
if (this.shouldSpreadLiquid(world, pos, state)) {
|
||||||
- world.getLiquidTicks().scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay((LevelReader) world));
|
- world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world));
|
||||||
+ world.getLiquidTicks().scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
+ world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -14,11 +14,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
log("Creeper lingering effect: " + disableCreeperLingeringEffect);
|
log("Creeper lingering effect: " + disableCreeperLingeringEffect);
|
||||||
}
|
}
|
||||||
+
|
+
|
||||||
+ public double squidMaxSpawnHeight;
|
|
||||||
+ private void squidMaxSpawnHeight() {
|
|
||||||
+ squidMaxSpawnHeight = getDouble("squid-spawn-height.maximum", 0.0D);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public boolean disableSprintInterruptionOnAttack;
|
+ public boolean disableSprintInterruptionOnAttack;
|
||||||
+ private void disableSprintInterruptionOnAttack() {
|
+ private void disableSprintInterruptionOnAttack() {
|
||||||
+ disableSprintInterruptionOnAttack = getBoolean("game-mechanics.disable-sprint-interruption-on-attack", false);
|
+ disableSprintInterruptionOnAttack = getBoolean("game-mechanics.disable-sprint-interruption-on-attack", false);
|
||||||
|
39
patches/server/Optimize-MappedRegistry.patch
Normale Datei
39
patches/server/Optimize-MappedRegistry.patch
Normale Datei
@ -0,0 +1,39 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Aikar <aikar@aikar.co>
|
||||||
|
Date: Sun, 26 Aug 2018 20:49:50 -0400
|
||||||
|
Subject: [PATCH] Optimize MappedRegistry
|
||||||
|
|
||||||
|
Use larger initial sizes to increase bucket capacity on the BiMap
|
||||||
|
|
||||||
|
BiMap.get was seen to be using a good bit of CPU time.
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||||
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
|
--- a/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||||
|
+++ b/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||||
|
@@ -0,0 +0,0 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
|
||||||
|
|
||||||
|
protected static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
private final ObjectList<T> byId = new ObjectArrayList(256);
|
||||||
|
- private final Object2IntMap<T> toId = (Object2IntMap) Util.make(new Object2IntOpenCustomHashMap(Util.identityStrategy()), (object2intopencustomhashmap) -> {
|
||||||
|
- object2intopencustomhashmap.defaultReturnValue(-1);
|
||||||
|
- });
|
||||||
|
- private final BiMap<ResourceLocation, T> storage = HashBiMap.create();
|
||||||
|
- private final BiMap<ResourceKey<T>, T> keyStorage = HashBiMap.create();
|
||||||
|
- private final Map<T, Lifecycle> lifecycles = Maps.newIdentityHashMap();
|
||||||
|
+ private final it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap<T> toId = new it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap<T>(2048);// Paper - use bigger expected size to reduce collisions and direct intent for FastUtil to be identity map
|
||||||
|
+ private final BiMap<ResourceLocation, T> storage = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
|
||||||
|
+ private final BiMap<ResourceKey<T>, T> keyStorage = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
|
||||||
|
+ private final Map<T, Lifecycle> lifecycles = new java.util.IdentityHashMap<>(2048); // Paper - use bigger expected size to reduce collisions
|
||||||
|
private Lifecycle elementsLifecycle;
|
||||||
|
@Nullable
|
||||||
|
protected Object[] randomCache;
|
||||||
|
@@ -0,0 +0,0 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
|
||||||
|
|
||||||
|
public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle lifecycle) {
|
||||||
|
super(key, lifecycle);
|
||||||
|
- this.elementsLifecycle = lifecycle;
|
||||||
|
+ this.toId.defaultReturnValue(-1); // Paper
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> MapCodec<MappedRegistry.RegistryEntry<T>> withNameAndId(ResourceKey<? extends Registry<T>> key, MapCodec<T> entryCodec) {
|
@ -85,7 +85,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||||
this.slime.lookAt((Entity) this.slime.getTarget(), 10.0F, 10.0F);
|
|
||||||
((Slime.SlimeMoveControl) this.slime.getMoveControl()).setDirection(this.slime.getYRot(), this.slime.isDealsDamage());
|
((Slime.SlimeMoveControl) this.slime.getMoveControl()).setDirection(this.slime.getYRot(), this.slime.isDealsDamage());
|
||||||
}
|
}
|
||||||
+
|
+
|
||||||
@ -107,12 +107,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||||
if (--this.nextRandomizeTime <= 0) {
|
if (--this.nextRandomizeTime <= 0) {
|
||||||
this.nextRandomizeTime = 40 + this.slime.getRandom().nextInt(60);
|
this.nextRandomizeTime = this.adjustedTickDelay(40 + this.slime.getRandom().nextInt(60));
|
||||||
- this.chosenDegrees = (float) this.slime.getRandom().nextInt(360);
|
this.chosenDegrees = (float) this.slime.getRandom().nextInt(360);
|
||||||
+ // Paper start
|
+ // Paper start
|
||||||
+ SlimeChangeDirectionEvent event = new SlimeChangeDirectionEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (float) this.slime.getRandom().nextInt(360));
|
+ SlimeChangeDirectionEvent event = new SlimeChangeDirectionEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), this.chosenDegrees);
|
||||||
+ if (!this.slime.canWander || !event.callEvent()) return;
|
+ if (!this.slime.canWander || !event.callEvent()) return;
|
||||||
+ this.chosenDegrees = event.getNewYaw();
|
+ this.chosenDegrees = event.getNewYaw();
|
||||||
+ // Paper end
|
+ // Paper end
|
@ -3,6 +3,9 @@ From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
|||||||
Date: Sat, 13 Jul 2019 09:23:10 -0700
|
Date: Sat, 13 Jul 2019 09:23:10 -0700
|
||||||
Subject: [PATCH] Asynchronous chunk IO and loading
|
Subject: [PATCH] Asynchronous chunk IO and loading
|
||||||
|
|
||||||
|
# UPDATE NOTES: RegionFileStorage and SectionStorage need resolving (will conflict on apply)
|
||||||
|
# ChunkSerializer needs the new tick lists to be saved (see added todos)
|
||||||
|
|
||||||
This patch re-adds a file IO thread as well as shoving de-serializing
|
This patch re-adds a file IO thread as well as shoving de-serializing
|
||||||
chunk NBT data onto worker threads. This patch also will shove
|
chunk NBT data onto worker threads. This patch also will shove
|
||||||
chunk data serialization onto the same worker threads when the chunk
|
chunk data serialization onto the same worker threads when the chunk
|
||||||
@ -2282,8 +2285,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
--- a/src/main/java/net/minecraft/server/MCUtil.java
|
--- a/src/main/java/net/minecraft/server/MCUtil.java
|
||||||
+++ b/src/main/java/net/minecraft/server/MCUtil.java
|
+++ b/src/main/java/net/minecraft/server/MCUtil.java
|
||||||
@@ -0,0 +0,0 @@ public final class MCUtil {
|
@@ -0,0 +0,0 @@ public final class MCUtil {
|
||||||
return null;
|
public static int getTicketLevelFor(net.minecraft.world.level.chunk.ChunkStatus status) {
|
||||||
}
|
return net.minecraft.server.level.ChunkMap.MAX_VIEW_DISTANCE + net.minecraft.world.level.chunk.ChunkStatus.getDistance(status);
|
||||||
}
|
}
|
||||||
+
|
+
|
||||||
+ public static int getTicketLevelFor(net.minecraft.world.level.chunk.ChunkStatus status) {
|
+ public static int getTicketLevelFor(net.minecraft.world.level.chunk.ChunkStatus status) {
|
||||||
@ -2296,7 +2299,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+++ b/src/main/java/net/minecraft/server/Main.java
|
+++ b/src/main/java/net/minecraft/server/Main.java
|
||||||
@@ -0,0 +0,0 @@ public class Main {
|
@@ -0,0 +0,0 @@ public class Main {
|
||||||
|
|
||||||
convertable_conversionsession.a((IRegistryCustom) iregistrycustom_dimension, (SaveData) object);
|
convertable_conversionsession.saveDataTag(iregistrycustom_dimension, (SaveData) object);
|
||||||
*/
|
*/
|
||||||
+ Class.forName(net.minecraft.world.entity.npc.VillagerTrades.class.getName());// Paper - load this sync so it won't fail later async
|
+ Class.forName(net.minecraft.world.entity.npc.VillagerTrades.class.getName());// Paper - load this sync so it won't fail later async
|
||||||
final DedicatedServer dedicatedserver = (DedicatedServer) MinecraftServer.spin((thread) -> {
|
final DedicatedServer dedicatedserver = (DedicatedServer) MinecraftServer.spin((thread) -> {
|
||||||
@ -2364,18 +2367,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
- this.flushWorker();
|
- this.flushWorker();
|
||||||
|
+ //this.flushWorker(); // Paper - nuke IOWorker
|
||||||
+ this.level.asyncChunkTaskManager.flush(); // Paper - flush to preserve behavior compat with pre-async behaviour
|
+ this.level.asyncChunkTaskManager.flush(); // Paper - flush to preserve behavior compat with pre-async behaviour
|
||||||
+// this.i(); // Paper - nuke IOWorker
|
|
||||||
} else {
|
} else {
|
||||||
this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).forEach((playerchunk) -> {
|
this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).forEach((playerchunk) -> {
|
||||||
ChunkAccess ichunkaccess = (ChunkAccess) playerchunk.getChunkToSave().getNow(null); // CraftBukkit - decompile error
|
ChunkAccess ichunkaccess = (ChunkAccess) playerchunk.getChunkToSave().getNow(null); // CraftBukkit - decompile error
|
||||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
- private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.96; // Spigot
|
|
||||||
+ private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.90; // Spigot // Paper - unload more
|
|
||||||
|
|
||||||
protected void tick(BooleanSupplier shouldKeepTicking) {
|
protected void tick(BooleanSupplier shouldKeepTicking) {
|
||||||
ProfilerFiller gameprofilerfiller = this.level.getProfiler();
|
ProfilerFiller gameprofilerfiller = this.level.getProfiler();
|
||||||
|
|
||||||
@ -2387,10 +2384,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
if (!this.level.noSave()) {
|
if (!this.level.noSave()) {
|
||||||
+ try (Timing ignored = this.level.timings.chunkUnload.startTiming()) { // Paper
|
+ try (Timing ignored = this.level.timings.chunkUnload.startTiming()) { // Paper
|
||||||
this.processUnloads(shouldKeepTicking);
|
this.processUnloads(shouldKeepTicking);
|
||||||
+ }// Paper
|
+ } // Paper
|
||||||
}
|
}
|
||||||
|
|
||||||
gameprofilerfiller.pop();
|
gameprofilerfiller.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
- private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.96; // Spigot
|
||||||
|
+ private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.90; // Spigot // Paper - unload more
|
||||||
|
|
||||||
|
private void processUnloads(BooleanSupplier shouldKeepTicking) {
|
||||||
|
LongIterator longiterator = this.toDrop.iterator();
|
||||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
if (playerchunk != null) {
|
if (playerchunk != null) {
|
||||||
this.pendingUnloads.put(j, playerchunk);
|
this.pendingUnloads.put(j, playerchunk);
|
||||||
@ -2402,7 +2406,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
}
|
}
|
||||||
// Spigot end
|
// Spigot end
|
||||||
- this.scheduleUnload(j, playerchunk);
|
- this.scheduleUnload(j, playerchunk);
|
||||||
+ //this.a(j, playerchunk); // Paper - move up because spigot did a dumb
|
+ //this.scheduleUnload(j, playerchunk); // Paper - move up because spigot did a dumb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
activityAccountant.endActivity(); // Spigot
|
activityAccountant.endActivity(); // Spigot
|
||||||
@ -2418,7 +2422,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ ChunkPos chunkPos = chunk.getPos();
|
+ ChunkPos chunkPos = chunk.getPos();
|
||||||
+ CompoundTag poiData;
|
+ CompoundTag poiData;
|
||||||
+ try (Timing ignored = this.level.timings.chunkUnloadPOISerialization.startTiming()) {
|
+ try (Timing ignored = this.level.timings.chunkUnloadPOISerialization.startTiming()) {
|
||||||
+ poiData = this.getVillagePlace().getData(chunk.getPos());
|
+ poiData = this.poiManager.getData(chunk.getPos());
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.level, chunkPos.x, chunkPos.z,
|
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.level, chunkPos.x, chunkPos.z,
|
||||||
@ -2467,7 +2471,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ LOGGER.fatal("Failed to prepare async save, attempting synchronous save", ex);
|
+ LOGGER.fatal("Failed to prepare async save, attempting synchronous save", ex);
|
||||||
+ this.save(ichunkaccess);
|
+ this.save(ichunkaccess);
|
||||||
+ }
|
+ }
|
||||||
+ // Paper end - async chunk saving
|
+ // Paper end - async chunk savin
|
||||||
if (this.entitiesInLevel.remove(pos) && ichunkaccess instanceof LevelChunk) {
|
if (this.entitiesInLevel.remove(pos) && ichunkaccess instanceof LevelChunk) {
|
||||||
LevelChunk chunk = (LevelChunk) ichunkaccess;
|
LevelChunk chunk = (LevelChunk) ichunkaccess;
|
||||||
|
|
||||||
@ -2484,30 +2488,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
- try (Timing ignored2 = this.level.timings.chunkIO.startTimingIfSync()) { // Paper start - timings
|
- try (Timing ignored2 = this.level.timings.chunkIO.startTimingIfSync()) { // Paper start - timings
|
||||||
- nbttagcompound = this.readChunk(pos);
|
- nbttagcompound = this.readChunk(pos);
|
||||||
- } // Paper end
|
- } // Paper end
|
||||||
|
-
|
||||||
|
- if (nbttagcompound != null) {try (Timing ignored2 = this.level.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings
|
||||||
|
- boolean flag = nbttagcompound.contains("Status", 8);
|
||||||
|
-
|
||||||
|
- if (flag) {
|
||||||
|
- ProtoChunk protochunk = ChunkSerializer.read(this.level, this.poiManager, pos, nbttagcompound);
|
||||||
+ // Paper start
|
+ // Paper start
|
||||||
+ if (ioThrowable != null) {
|
+ if (ioThrowable != null) {
|
||||||
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ioThrowable);
|
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ioThrowable);
|
||||||
+ }
|
+ }
|
||||||
|
+ this.poiManager.loadInData(pos, chunkHolder.poiData);
|
||||||
- if (nbttagcompound != null) {try (Timing ignored2 = this.level.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings
|
|
||||||
- boolean flag = nbttagcompound.contains("Level", 10) && nbttagcompound.getCompound("Level").contains("Status", 8);
|
|
||||||
+ this.getVillagePlace().loadInData(pos, chunkHolder.poiData);
|
|
||||||
+ chunkHolder.tasks.forEach(Runnable::run);
|
+ chunkHolder.tasks.forEach(Runnable::run);
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
|
|
||||||
- if (flag) {
|
|
||||||
- ProtoChunk protochunk = ChunkSerializer.read(this.level, this.structureManager, this.poiManager, pos, nbttagcompound);
|
|
||||||
+ if (chunkHolder.protoChunk != null) {try (Timing ignored2 = this.level.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings // Paper - chunk is created async
|
+ if (chunkHolder.protoChunk != null) {try (Timing ignored2 = this.level.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings // Paper - chunk is created async
|
||||||
+
|
|
||||||
+ if (true) {
|
+ if (true) {
|
||||||
+ ProtoChunk protochunk = chunkHolder.protoChunk;
|
|
||||||
|
|
||||||
this.markPosition(pos, protochunk.getStatus().getChunkType());
|
this.markPosition(pos, protochunk.getStatus().getChunkType());
|
||||||
return Either.left(protochunk);
|
return Either.left(protochunk);
|
||||||
|
}
|
||||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
|
|
||||||
this.markPositionReplaceable(pos);
|
this.markPositionReplaceable(pos);
|
||||||
return Either.left(new ProtoChunk(pos, UpgradeData.EMPTY, this.level));
|
return Either.left(new ProtoChunk(pos, UpgradeData.EMPTY, this.level, this.level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), (BlendingData) null));
|
||||||
- }, this.mainThreadExecutor);
|
- }, this.mainThreadExecutor);
|
||||||
+ // Paper start - Async chunk io
|
+ // Paper start - Async chunk io
|
||||||
+ };
|
+ };
|
||||||
@ -2537,7 +2540,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ // Paper end
|
+ // Paper end
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markPositionReplaceable(ChunkPos chunkcoordintpair) {
|
private void markPositionReplaceable(ChunkPos pos) {
|
||||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2560,13 +2563,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
|
|
||||||
this.level.getProfiler().incrementCounter("chunkSave");
|
this.level.getProfiler().incrementCounter("chunkSave");
|
||||||
- CompoundTag nbttagcompound = ChunkSerializer.write(this.level, chunk);
|
- CompoundTag nbttagcompound = ChunkSerializer.write(this.level, chunk);
|
||||||
|
-
|
||||||
|
- this.write(chunkcoordintpair, nbttagcompound);
|
||||||
+ CompoundTag nbttagcompound;
|
+ CompoundTag nbttagcompound;
|
||||||
+ try (co.aikar.timings.Timing ignored1 = this.level.timings.chunkSaveDataSerialization.startTiming()) { // Paper
|
+ try (co.aikar.timings.Timing ignored1 = this.level.timings.chunkSaveDataSerialization.startTiming()) { // Paper
|
||||||
+ nbttagcompound = ChunkSerializer.write(this.level, chunk);
|
+ nbttagcompound = ChunkSerializer.write(this.level, chunk);
|
||||||
+ } // Paper
|
+ } // Paper;
|
||||||
+
|
+
|
||||||
|
|
||||||
- this.write(chunkcoordintpair, nbttagcompound);
|
|
||||||
+ // Paper start - async chunk io
|
+ // Paper start - async chunk io
|
||||||
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.level, chunkcoordintpair.x, chunkcoordintpair.z,
|
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.level, chunkcoordintpair.x, chunkcoordintpair.z,
|
||||||
+ null, nbttagcompound, com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY);
|
+ null, nbttagcompound, com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY);
|
||||||
@ -2581,7 +2584,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ } // Paper
|
+ } // Paper
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isExistingChunkFull(ChunkPos chunkcoordintpair) {
|
private boolean isExistingChunkFull(ChunkPos pos) {
|
||||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2618,14 +2621,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
@Nullable
|
@Nullable
|
||||||
public CompoundTag readChunk(ChunkPos pos) throws IOException {
|
public CompoundTag readChunk(ChunkPos pos) throws IOException {
|
||||||
CompoundTag nbttagcompound = this.read(pos);
|
CompoundTag nbttagcompound = this.read(pos);
|
||||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
+ @Deprecated public PoiManager getVillagePlace() { return this.getPoiManager(); } // Paper - OBFHELPER
|
|
||||||
protected PoiManager getPoiManager() {
|
|
||||||
return this.poiManager;
|
|
||||||
}
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||||
@ -2765,7 +2760,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
gameprofilerfiller.incrementCounter("getChunkCacheMiss");
|
gameprofilerfiller.incrementCounter("getChunkCacheMiss");
|
||||||
- CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create);
|
- CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create);
|
||||||
+ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create, true); // Paper
|
+ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create, true); // Paper
|
||||||
ServerChunkCache.MainThreadExecutor chunkproviderserver_a = this.mainThreadProcessor;
|
ServerChunkCache.MainThreadExecutor chunkproviderserver_b = this.mainThreadProcessor;
|
||||||
|
|
||||||
Objects.requireNonNull(completablefuture);
|
Objects.requireNonNull(completablefuture);
|
||||||
if (!completablefuture.isDone()) { // Paper
|
if (!completablefuture.isDone()) { // Paper
|
||||||
@ -2774,7 +2769,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ com.destroystokyo.paper.io.chunk.ChunkTaskManager.pushChunkWait(this.level, x1, z1);
|
+ com.destroystokyo.paper.io.chunk.ChunkTaskManager.pushChunkWait(this.level, x1, z1);
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
this.level.timings.syncChunkLoad.startTiming(); // Paper
|
this.level.timings.syncChunkLoad.startTiming(); // Paper
|
||||||
chunkproviderserver_a.managedBlock(completablefuture::isDone);
|
chunkproviderserver_b.managedBlock(completablefuture::isDone);
|
||||||
+ com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug
|
+ com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug
|
||||||
this.level.timings.syncChunkLoad.stopTiming(); // Paper
|
this.level.timings.syncChunkLoad.stopTiming(); // Paper
|
||||||
} // Paper
|
} // Paper
|
||||||
@ -2937,8 +2932,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
private final LongSet loadedChunks = new LongOpenHashSet();
|
private final LongSet loadedChunks = new LongOpenHashSet();
|
||||||
+ private final net.minecraft.server.level.ServerLevel world; // Paper
|
+ private final net.minecraft.server.level.ServerLevel world; // Paper
|
||||||
|
|
||||||
public PoiManager(File directory, DataFixer dataFixer, boolean dsync, LevelHeightAccessor world) {
|
public PoiManager(Path path, DataFixer dataFixer, boolean dsync, LevelHeightAccessor world) {
|
||||||
super(directory, PoiSection::codec, PoiSection::new, dataFixer, DataFixTypes.POI_CHUNK, dsync, world);
|
super(path, PoiSection::codec, PoiSection::new, dataFixer, DataFixTypes.POI_CHUNK, dsync, world);
|
||||||
+ this.world = (net.minecraft.server.level.ServerLevel)world; // Paper
|
+ this.world = (net.minecraft.server.level.ServerLevel)world; // Paper
|
||||||
this.distanceTracker = new PoiManager.DistanceTracker();
|
this.distanceTracker = new PoiManager.DistanceTracker();
|
||||||
}
|
}
|
||||||
@ -2999,32 +2994,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
public static enum Occupancy {
|
public static enum Occupancy {
|
||||||
HAS_SPACE(PoiRecord::hasSpace),
|
HAS_SPACE(PoiRecord::hasSpace),
|
||||||
IS_OCCUPIED(PoiRecord::isOccupied),
|
IS_OCCUPIED(PoiRecord::isOccupied),
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/TickNextTickData.java b/src/main/java/net/minecraft/world/level/TickNextTickData.java
|
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
||||||
--- a/src/main/java/net/minecraft/world/level/TickNextTickData.java
|
|
||||||
+++ b/src/main/java/net/minecraft/world/level/TickNextTickData.java
|
|
||||||
@@ -0,0 +0,0 @@ import java.util.Comparator;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
|
|
||||||
public class TickNextTickData<T> {
|
|
||||||
- private static long counter;
|
|
||||||
+ private static final java.util.concurrent.atomic.AtomicLong COUNTER = new java.util.concurrent.atomic.AtomicLong(); // Paper - async chunk loading
|
|
||||||
private final T type;
|
|
||||||
public final BlockPos pos;
|
|
||||||
public final long triggerTick;
|
|
||||||
@@ -0,0 +0,0 @@ public class TickNextTickData<T> {
|
|
||||||
}
|
|
||||||
|
|
||||||
public TickNextTickData(BlockPos pos, T t, long time, TickPriority priority) {
|
|
||||||
- this.c = (long)(counter++);
|
|
||||||
+ this.c = (TickNextTickData.COUNTER.getAndIncrement()); // Paper - async chunk loading
|
|
||||||
this.pos = pos.immutable();
|
|
||||||
this.type = t;
|
|
||||||
this.triggerTick = time;
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||||
|
@@ -0,0 +0,0 @@ import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
|
import net.minecraft.world.level.material.Fluid;
|
||||||
|
import net.minecraft.world.ticks.LevelChunkTicks;
|
||||||
|
import net.minecraft.world.ticks.ProtoChunkTicks;
|
||||||
|
+import net.minecraft.world.ticks.TickContainerAccess;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||||
|
|
||||||
public ChunkSerializer() {}
|
public ChunkSerializer() {}
|
||||||
@ -3044,56 +3025,50 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ }
|
+ }
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
+
|
+
|
||||||
public static ProtoChunk read(ServerLevel world, StructureManager structureManager, PoiManager poiStorage, ChunkPos pos, CompoundTag nbt) {
|
public static ProtoChunk read(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt) {
|
||||||
+ // Paper start - add variant for async calls
|
+ // Paper start - add variant for async calls
|
||||||
+ InProgressChunkHolder holder = loadChunk(world, structureManager, poiStorage, pos, nbt, true);
|
+ InProgressChunkHolder holder = loadChunk(world, poiStorage, chunkPos, nbt, true);
|
||||||
+ holder.tasks.forEach(Runnable::run);
|
+ holder.tasks.forEach(Runnable::run);
|
||||||
+ return holder.protoChunk;
|
+ return holder.protoChunk;
|
||||||
+ }
|
+ }
|
||||||
+ public static InProgressChunkHolder loadChunk(ServerLevel world, StructureManager structureManager, PoiManager poiStorage, ChunkPos pos, CompoundTag nbt, boolean distinguish) {
|
+
|
||||||
|
+ public static InProgressChunkHolder loadChunk(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt, boolean distinguish) {
|
||||||
+ java.util.ArrayDeque<Runnable> tasksToExecuteOnMain = new java.util.ArrayDeque<>();
|
+ java.util.ArrayDeque<Runnable> tasksToExecuteOnMain = new java.util.ArrayDeque<>();
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator();
|
ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos"));
|
||||||
BiomeSource worldchunkmanager = chunkgenerator.getBiomeSource();
|
|
||||||
CompoundTag nbttagcompound1 = nbt.getCompound("Level");
|
if (!Objects.equals(chunkPos, chunkcoordintpair1)) {
|
||||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||||
LevelLightEngine lightengine = chunkproviderserver.getLightEngine();
|
LevelLightEngine lightengine = chunkproviderserver.getLightEngine();
|
||||||
|
|
||||||
if (flag) {
|
if (flag) {
|
||||||
+ tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main
|
+ tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main
|
||||||
lightengine.retainData(pos, true);
|
lightengine.retainData(chunkPos, true);
|
||||||
+ }); // Paper - delay this task since we're executing off-main
|
+ }); // Paper - delay this task since we're executing off-main
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < nbttaglist.size(); ++j) {
|
Registry<Biome> iregistry = world.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
||||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||||
achunksection[world.getSectionIndexFromSectionY(b0)] = chunksection;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main
|
|
||||||
poiStorage.checkConsistencyWithBlocks(pos, chunksection);
|
|
||||||
+ }); // Paper - delay this task since we're executing off-main
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag) {
|
if (flag) {
|
||||||
if (nbttagcompound2.contains("BlockLight", 7)) {
|
if (nbttagcompound1.contains("BlockLight", 7)) {
|
||||||
- lightengine.queueSectionData(LightLayer.BLOCK, SectionPos.of(pos, b0), new DataLayer(nbttagcompound2.getByteArray("BlockLight")), true);
|
- lightengine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkPos, b0), new DataLayer(nbttagcompound1.getByteArray("BlockLight")), true);
|
||||||
+ // Paper start - delay this task since we're executing off-main
|
+ // Paper start - delay this task since we're executing off-main
|
||||||
+ DataLayer blockLight = new DataLayer(nbttagcompound2.getByteArray("BlockLight"));
|
+ DataLayer blockLight = new DataLayer(nbttagcompound1.getByteArray("BlockLight"));
|
||||||
+ tasksToExecuteOnMain.add(() -> {
|
+ tasksToExecuteOnMain.add(() -> {
|
||||||
+ lightengine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkcoordintpair1, b0), blockLight, true);
|
+ lightengine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkcoordintpair1, b0), blockLight, true);
|
||||||
+ });
|
+ });
|
||||||
+ // Paper end - delay this task since we're executing off-main
|
+ // Paper end - delay this task since we're executing off-main
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag1 && nbttagcompound2.contains("SkyLight", 7)) {
|
if (flag1 && nbttagcompound1.contains("SkyLight", 7)) {
|
||||||
- lightengine.queueSectionData(LightLayer.SKY, SectionPos.of(pos, b0), new DataLayer(nbttagcompound2.getByteArray("SkyLight")), true);
|
- lightengine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkPos, b0), new DataLayer(nbttagcompound1.getByteArray("SkyLight")), true);
|
||||||
+ // Paper start - delay this task since we're executing off-main
|
+ // Paper start - delay this task since we're executing off-main
|
||||||
+ DataLayer skyLight = new DataLayer(nbttagcompound2.getByteArray("SkyLight"));
|
+ DataLayer skyLight = new DataLayer(nbttagcompound1.getByteArray("SkyLight"));
|
||||||
+ tasksToExecuteOnMain.add(() -> {
|
+ tasksToExecuteOnMain.add(() -> {
|
||||||
+ lightengine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkcoordintpair1, b0), skyLight, true);
|
+ lightengine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkcoordintpair1, b0), skyLight, true);
|
||||||
+ });
|
+ });
|
||||||
+ // Paper end - delay this task since we're executing off-main
|
+ // Paper end - delay this task since we're executing off-mai
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3101,20 +3076,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (chunkstatus_type == ChunkStatus.ChunkType.LEVELCHUNK) {
|
if (chunkstatus_type == ChunkStatus.ChunkType.LEVELCHUNK) {
|
||||||
- return new ImposterProtoChunk((LevelChunk) object);
|
- return new ImposterProtoChunk((LevelChunk) object, false);
|
||||||
+ return new InProgressChunkHolder(new ImposterProtoChunk((LevelChunk) object), tasksToExecuteOnMain); // Paper - Async chunk loading
|
+ return new InProgressChunkHolder(new ImposterProtoChunk((LevelChunk) object, false), tasksToExecuteOnMain); // Paper - Async chunk loading
|
||||||
} else {
|
} else {
|
||||||
ProtoChunk protochunk1 = (ProtoChunk) object;
|
ProtoChunk protochunk1 = (ProtoChunk) object;
|
||||||
|
|
||||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||||
protochunk1.setCarvingMask(worldgenstage_features, BitSet.valueOf(nbttagcompound5.getByteArray(s1)));
|
protochunk1.setCarvingMask(worldgenstage_features, new CarvingMask(nbttagcompound4.getLongArray(s1), ((ChunkAccess) object).getMinBuildHeight()));
|
||||||
}
|
}
|
||||||
|
|
||||||
- return protochunk1;
|
- return protochunk1;
|
||||||
+ return new InProgressChunkHolder(protochunk1, tasksToExecuteOnMain); // Paper - Async chunk loading
|
+ return new InProgressChunkHolder(protochunk1, tasksToExecuteOnMain); // Paper - Async chunk loading
|
||||||
+ }
|
}
|
||||||
+ }
|
}
|
||||||
+
|
|
||||||
+ // Paper start - async chunk save for unload
|
+ // Paper start - async chunk save for unload
|
||||||
+ public static final class AsyncSaveData {
|
+ public static final class AsyncSaveData {
|
||||||
+ public final DataLayer[] blockLight;
|
+ public final DataLayer[] blockLight;
|
||||||
@ -3163,8 +3138,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ skyLight[i - lightenginethreaded.getMinLightSection()] = skyArray;
|
+ skyLight[i - lightenginethreaded.getMinLightSection()] = skyArray;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ TickList<Block> blockTickList = chunk.getBlockTicks();
|
+ TickContainerAccess<Block> blockTickList = chunk.getBlockTicks();
|
||||||
+
|
+
|
||||||
|
+ //TODO check ChunkSerializer "block_ticks"
|
||||||
+ ListTag blockTickListSerialized;
|
+ ListTag blockTickListSerialized;
|
||||||
+ if (blockTickList instanceof ProtoTickList || blockTickList instanceof ChunkTickList) {
|
+ if (blockTickList instanceof ProtoTickList || blockTickList instanceof ChunkTickList) {
|
||||||
+ blockTickListSerialized = null;
|
+ blockTickListSerialized = null;
|
||||||
@ -3172,13 +3148,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ blockTickListSerialized = world.getBlockTicks().save(chunkPos);
|
+ blockTickListSerialized = world.getBlockTicks().save(chunkPos);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ TickList<Fluid> fluidTickList = chunk.getLiquidTicks();
|
+ TickContainerAccess<Fluid> fluidTickList = chunk.getFluidTicks();
|
||||||
+
|
+
|
||||||
|
+ //TODO
|
||||||
+ ListTag fluidTickListSerialized;
|
+ ListTag fluidTickListSerialized;
|
||||||
+ if (fluidTickList instanceof ProtoTickList || fluidTickList instanceof ChunkTickList) {
|
+ if (fluidTickList instanceof ProtoTickList || fluidTickList instanceof ChunkTickList) {
|
||||||
+ fluidTickListSerialized = null;
|
+ fluidTickListSerialized = null;
|
||||||
+ } else {
|
+ } else {
|
||||||
+ fluidTickListSerialized = world.getLiquidTicks().save(chunkPos);
|
+ fluidTickListSerialized = world.getFluidTicks().save(chunkPos);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ ListTag blockEntitiesSerialized = new ListTag();
|
+ ListTag blockEntitiesSerialized = new ListTag();
|
||||||
@ -3187,9 +3164,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ if (blockEntityNbt != null) {
|
+ if (blockEntityNbt != null) {
|
||||||
+ blockEntitiesSerialized.add(blockEntityNbt);
|
+ blockEntitiesSerialized.add(blockEntityNbt);
|
||||||
+ }
|
+ }
|
||||||
}
|
+ }
|
||||||
+
|
+
|
||||||
+ return new AsyncSaveData(blockLight, skyLight, blockTickListSerialized, fluidTickListSerialized, blockEntitiesSerialized, world.getGameTime());
|
+ return new AsyncSaveData(blockLight, skyLight, blockTickListSerialized, fluidTickListSerialized, blockEntitiesSerialized, world.getGameTime());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
private static void logErrors(ChunkPos chunkPos, int y, String message) {
|
||||||
|
ChunkSerializer.LOGGER.error("Recoverable errors when loading section [" + chunkPos.x + ", " + y + ", " + chunkPos.z + "]: " + message);
|
||||||
|
}
|
||||||
|
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompoundTag write(ServerLevel world, ChunkAccess chunk) {
|
public static CompoundTag write(ServerLevel world, ChunkAccess chunk) {
|
||||||
@ -3199,23 +3182,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ // Paper end
|
+ // Paper end
|
||||||
ChunkPos chunkcoordintpair = chunk.getPos();
|
ChunkPos chunkcoordintpair = chunk.getPos();
|
||||||
CompoundTag nbttagcompound = new CompoundTag();
|
CompoundTag nbttagcompound = new CompoundTag();
|
||||||
CompoundTag nbttagcompound1 = new CompoundTag();
|
|
||||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||||
nbttagcompound.put("Level", nbttagcompound1);
|
nbttagcompound.putInt("yPos", chunk.getMinSection());
|
||||||
nbttagcompound1.putInt("xPos", chunkcoordintpair.x);
|
nbttagcompound.putInt("zPos", chunkcoordintpair.z);
|
||||||
nbttagcompound1.putInt("zPos", chunkcoordintpair.z);
|
nbttagcompound.putLong("LastUpdate", world.getGameTime());
|
||||||
- nbttagcompound1.putLong("LastUpdate", world.getGameTime());
|
+ nbttagcompound.putLong("LastUpdate", asyncsavedata != null ? asyncsavedata.worldTime : world.getGameTime()); // Paper - async chunk unloading
|
||||||
+ nbttagcompound1.putLong("LastUpdate", asyncsavedata != null ? asyncsavedata.worldTime : world.getGameTime()); // Paper - async chunk unloading
|
nbttagcompound.putLong("InhabitedTime", chunk.getInhabitedTime());
|
||||||
nbttagcompound1.putLong("InhabitedTime", chunk.getInhabitedTime());
|
nbttagcompound.putString("Status", chunk.getStatus().getName());
|
||||||
nbttagcompound1.putString("Status", chunk.getStatus().getName());
|
BlendingData blendingdata = chunk.getBlendingData();
|
||||||
UpgradeData chunkconverter = chunk.getUpgradeData();
|
|
||||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||||
LevelChunkSection chunksection = (LevelChunkSection) Arrays.stream(achunksection).filter((chunksection1) -> {
|
for (int i = lightenginethreaded.getMinLightSection(); i < lightenginethreaded.getMaxLightSection(); ++i) {
|
||||||
return chunksection1 != null && SectionPos.blockToSectionCoord(chunksection1.bottomBlockY()) == finalI; // CraftBukkit - decompile errors
|
int j = chunk.getSectionIndexFromSectionY(i);
|
||||||
}).findFirst().orElse(LevelChunk.EMPTY_SECTION);
|
boolean flag1 = j >= 0 && j < achunksection.length;
|
||||||
- DataLayer nibblearray = lightenginethreaded.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(chunkcoordintpair, i));
|
- DataLayer nibblearray = lightenginethreaded.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(chunkcoordintpair, i));
|
||||||
- DataLayer nibblearray1 = lightenginethreaded.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(chunkcoordintpair, i));
|
- DataLayer nibblearray1 = lightenginethreaded.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(chunkcoordintpair, i));
|
||||||
-
|
|
||||||
+ // Paper start - async chunk save for unload
|
+ // Paper start - async chunk save for unload
|
||||||
+ DataLayer nibblearray; // block light
|
+ DataLayer nibblearray; // block light
|
||||||
+ DataLayer nibblearray1; // sky light
|
+ DataLayer nibblearray1; // sky light
|
||||||
@ -3227,11 +3208,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ nibblearray1 = asyncsavedata.skyLight[i - lightenginethreaded.getMinLightSection()];
|
+ nibblearray1 = asyncsavedata.skyLight[i - lightenginethreaded.getMinLightSection()];
|
||||||
+ }
|
+ }
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
if (chunksection != LevelChunk.EMPTY_SECTION || nibblearray != null || nibblearray1 != null) {
|
|
||||||
CompoundTag nbttagcompound2 = new CompoundTag();
|
|
||||||
|
|
||||||
|
if (flag1 || nibblearray != null || nibblearray1 != null) {
|
||||||
|
CompoundTag nbttagcompound1 = new CompoundTag();
|
||||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||||
nbttagcompound1.putIntArray("Biomes", biomestorage.writeBiomes());
|
nbttagcompound.putBoolean("isLightOn", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
- ListTag nbttaglist1 = new ListTag();
|
- ListTag nbttaglist1 = new ListTag();
|
||||||
@ -3248,38 +3229,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ }
|
+ }
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
|
|
||||||
CompoundTag nbttagcompound3;
|
CompoundTag nbttagcompound2;
|
||||||
|
|
||||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
||||||
nbttagcompound1.put("ToBeTicked", ((ProtoTickList) ticklist).save());
|
private static void saveTicks(ServerLevel world, CompoundTag nbt, ChunkAccess.TicksToSave tickSchedulers) {
|
||||||
} else if (ticklist instanceof ChunkTickList) {
|
long i = world.getLevelData().getGameTime();
|
||||||
nbttagcompound1.put("TileTicks", ((ChunkTickList) ticklist).save());
|
|
||||||
+ // Paper start - async chunk save for unload
|
+ //TODO original patch line 3259
|
||||||
+ } else if (asyncsavedata != null) {
|
nbt.put("block_ticks", tickSchedulers.blocks().save(i, (block) -> {
|
||||||
+ nbttagcompound1.put("TileTicks", asyncsavedata.blockTickList);
|
return Registry.BLOCK.getKey(block).toString();
|
||||||
+ // Paper end
|
}));
|
||||||
} else {
|
|
||||||
nbttagcompound1.put("TileTicks", world.getBlockTicks().save(chunkcoordintpair));
|
|
||||||
}
|
|
||||||
@@ -0,0 +0,0 @@ public class ChunkSerializer {
|
|
||||||
nbttagcompound1.put("LiquidsToBeTicked", ((ProtoTickList) ticklist1).save());
|
|
||||||
} else if (ticklist1 instanceof ChunkTickList) {
|
|
||||||
nbttagcompound1.put("LiquidTicks", ((ChunkTickList) ticklist1).save());
|
|
||||||
+ // Paper start - async chunk save for unload
|
|
||||||
+ } else if (asyncsavedata != null) {
|
|
||||||
+ nbttagcompound1.put("LiquidTicks", asyncsavedata.fluidTickList);
|
|
||||||
+ // Paper end
|
|
||||||
} else {
|
|
||||||
nbttagcompound1.put("LiquidTicks", world.getLiquidTicks().save(chunkcoordintpair));
|
|
||||||
}
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.storage.DimensionDataStorage;
|
@@ -0,0 +0,0 @@ import net.minecraft.world.level.storage.DimensionDataStorage;
|
||||||
|
|
||||||
public class ChunkStorage implements AutoCloseable {
|
public class ChunkStorage implements AutoCloseable {
|
||||||
|
|
||||||
|
public static final int LAST_MONOLYTH_STRUCTURE_DATA_VERSION = 1493;
|
||||||
- private final IOWorker worker;
|
- private final IOWorker worker;
|
||||||
+ // Paper - nuke IO worker
|
+ // Paper - nuke IO worker
|
||||||
protected final DataFixer fixerUpper;
|
protected final DataFixer fixerUpper;
|
||||||
@ -3291,7 +3258,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ public final RegionFileStorage regionFileCache;
|
+ public final RegionFileStorage regionFileCache;
|
||||||
+ // Paper end - async chunk loading
|
+ // Paper end - async chunk loading
|
||||||
|
|
||||||
public ChunkStorage(File directory, DataFixer dataFixer, boolean dsync) {
|
public ChunkStorage(Path directory, DataFixer dataFixer, boolean dsync) {
|
||||||
this.fixerUpper = dataFixer;
|
this.fixerUpper = dataFixer;
|
||||||
- this.worker = new IOWorker(directory, dsync, "chunk");
|
- this.worker = new IOWorker(directory, dsync, "chunk");
|
||||||
+ // Paper start - async chunk io
|
+ // Paper start - async chunk io
|
||||||
@ -3366,7 +3333,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
- this.worker.close();
|
- this.worker.close();
|
||||||
+ this.regionFileCache.close(); // Paper - nuke IO worker
|
+ this.regionFileCache.close(); // Paper - nuke IO worker
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public ChunkScanAccess chunkScanner() {
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||||
@ -3377,8 +3345,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
protected final RegionBitmap usedSectors;
|
protected final RegionBitmap usedSectors;
|
||||||
+ public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(true); // Paper
|
+ public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(true); // Paper
|
||||||
|
|
||||||
public RegionFile(File file, File directory, boolean dsync) throws IOException {
|
public RegionFile(Path path, Path path1, boolean dsync) throws IOException {
|
||||||
this(file.toPath(), directory.toPath(), RegionFileVersion.VERSION_DEFLATE, dsync);
|
this(path, path1, RegionFileVersion.VERSION_DEFLATE, dsync);
|
||||||
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
|
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
|
||||||
return (byteCount + 4096 - 1) / 4096;
|
return (byteCount + 4096 - 1) / 4096;
|
||||||
}
|
}
|
||||||
@ -3410,7 +3378,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ } // Paper end
|
+ } // Paper end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||||
@ -3418,7 +3386,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
||||||
this.sync = dsync;
|
this.sync = dsync;
|
||||||
}
|
}
|
||||||
|
|
||||||
- public RegionFile getFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit
|
- public RegionFile getFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit
|
||||||
+ // Paper start
|
+ // Paper start
|
||||||
+ public synchronized RegionFile getRegionFileIfLoaded(ChunkPos chunkcoordintpair) {
|
+ public synchronized RegionFile getRegionFileIfLoaded(ChunkPos chunkcoordintpair) {
|
||||||
@ -3438,7 +3406,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ // Paper end
|
+ // Paper end
|
||||||
long i = ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ());
|
long i = ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ());
|
||||||
RegionFile regionfile = (RegionFile) this.regionCache.getAndMoveToFirst(i);
|
RegionFile regionfile = (RegionFile) this.regionCache.getAndMoveToFirst(i);
|
||||||
|
|
||||||
if (regionfile != null) {
|
if (regionfile != null) {
|
||||||
+ // Paper start
|
+ // Paper start
|
||||||
+ if (lock) {
|
+ if (lock) {
|
||||||
@ -3451,7 +3419,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
if (this.regionCache.size() >= com.destroystokyo.paper.PaperConfig.regionFileCacheSize) { // Paper - configurable
|
if (this.regionCache.size() >= com.destroystokyo.paper.PaperConfig.regionFileCacheSize) { // Paper - configurable
|
||||||
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
||||||
RegionFile regionfile1 = new RegionFile(file1, this.folder, this.sync);
|
RegionFile regionfile1 = new RegionFile(file1, this.folder, this.sync);
|
||||||
|
|
||||||
this.regionCache.putAndMoveToFirst(i, regionfile1);
|
this.regionCache.putAndMoveToFirst(i, regionfile1);
|
||||||
+ // Paper start
|
+ // Paper start
|
||||||
+ if (lock) {
|
+ if (lock) {
|
||||||
@ -3474,23 +3442,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
+ try { // Paper
|
+ try { // Paper
|
||||||
DataInputStream datainputstream = regionfile.getChunkDataInputStream(pos);
|
DataInputStream datainputstream = regionfile.getChunkDataInputStream(pos);
|
||||||
|
|
||||||
CompoundTag nbttagcompound;
|
CompoundTag nbttagcompound;
|
||||||
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
return nbttagcompound;
|
return nbttagcompound;
|
||||||
+ } finally { // Paper start
|
+ } finally { // Paper start
|
||||||
+ regionfile.fileLock.unlock();
|
+ regionfile.fileLock.unlock();
|
||||||
+ } // Paper end
|
+ } // Paper end
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException {
|
protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException {
|
||||||
- RegionFile regionfile = this.getFile(pos, false); // CraftBukkit
|
- RegionFile regionfile = this.getFile(pos, false); // CraftBukkit
|
||||||
+ RegionFile regionfile = this.getFile(pos, false, true); // CraftBukkit // Paper
|
+ RegionFile regionfile = this.getFile(pos, false, true); // CraftBukkit // Paper
|
||||||
+ try { // Paper
|
+ try { // Paper
|
||||||
int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper
|
int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper
|
||||||
|
|
||||||
if (nbt == null) {
|
if (nbt == null) {
|
||||||
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
||||||
MinecraftServer.LOGGER.error("Failed to save chunk", laste);
|
MinecraftServer.LOGGER.error("Failed to save chunk", laste);
|
||||||
@ -3500,20 +3468,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ regionfile.fileLock.unlock();
|
+ regionfile.fileLock.unlock();
|
||||||
+ } // Paper end
|
+ } // Paper end
|
||||||
}
|
}
|
||||||
|
|
||||||
- public void close() throws IOException {
|
- public void close() throws IOException {
|
||||||
+ public synchronized void close() throws IOException { // Paper -> synchronized
|
+ public synchronized void close() throws IOException { // Paper -> synchronized
|
||||||
ExceptionCollector<IOException> exceptionsuppressor = new ExceptionCollector<>();
|
ExceptionCollector<IOException> exceptionsuppressor = new ExceptionCollector<>();
|
||||||
ObjectIterator objectiterator = this.regionCache.values().iterator();
|
ObjectIterator objectiterator = this.regionCache.values().iterator();
|
||||||
|
|
||||||
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
||||||
exceptionsuppressor.throwIfPresent();
|
exceptionsuppressor.throwIfPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
- public void flush() throws IOException {
|
- public void flush() throws IOException {
|
||||||
+ public synchronized void flush() throws IOException { // Paper - synchronize
|
+ public synchronized void flush() throws IOException { // Paper - synchronize
|
||||||
ObjectIterator objectiterator = this.regionCache.values().iterator();
|
ObjectIterator objectiterator = this.regionCache.values().iterator();
|
||||||
|
|
||||||
while (objectiterator.hasNext()) {
|
while (objectiterator.hasNext()) {
|
||||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
@ -3522,7 +3490,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.LevelHeightAccessor;
|
@@ -0,0 +0,0 @@ import net.minecraft.world.level.LevelHeightAccessor;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
-public class SectionStorage<R> implements AutoCloseable {
|
-public class SectionStorage<R> implements AutoCloseable {
|
||||||
+public class SectionStorage<R> extends RegionFileStorage implements AutoCloseable { // Paper - nuke IOWorker
|
+public class SectionStorage<R> extends RegionFileStorage implements AutoCloseable { // Paper - nuke IOWorker
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
@ -3534,7 +3502,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
private final Function<Runnable, Codec<R>> codec;
|
private final Function<Runnable, Codec<R>> codec;
|
||||||
@@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable {
|
@@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable {
|
||||||
protected final LevelHeightAccessor levelHeightAccessor;
|
protected final LevelHeightAccessor levelHeightAccessor;
|
||||||
|
|
||||||
public SectionStorage(File directory, Function<Runnable, Codec<R>> codecFactory, Function<Runnable, R> factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, LevelHeightAccessor world) {
|
public SectionStorage(File directory, Function<Runnable, Codec<R>> codecFactory, Function<Runnable, R> factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, LevelHeightAccessor world) {
|
||||||
+ super(directory, dsync); // Paper - nuke IOWorker
|
+ super(directory, dsync); // Paper - nuke IOWorker
|
||||||
this.codec = codecFactory;
|
this.codec = codecFactory;
|
||||||
@ -3545,11 +3513,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
- this.worker = new IOWorker(directory, dsync, directory.getName());
|
- this.worker = new IOWorker(directory, dsync, directory.getName());
|
||||||
+ // Paper - remove mojang I/O thread
|
+ // Paper - remove mojang I/O thread
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void tick(BooleanSupplier shouldKeepTicking) {
|
protected void tick(BooleanSupplier shouldKeepTicking) {
|
||||||
@@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable {
|
@@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readColumn(ChunkPos chunkPos) {
|
private void readColumn(ChunkPos chunkPos) {
|
||||||
- this.readColumn(chunkPos, NbtOps.INSTANCE, this.tryRead(chunkPos));
|
- this.readColumn(chunkPos, NbtOps.INSTANCE, this.tryRead(chunkPos));
|
||||||
+ // Paper start - expose function to load in data
|
+ // Paper start - expose function to load in data
|
||||||
@ -3559,7 +3527,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ this.readColumn(chunkPos, NbtOps.INSTANCE, compound);
|
+ this.readColumn(chunkPos, NbtOps.INSTANCE, compound);
|
||||||
+ // Paper end - expose function to load in data
|
+ // Paper end - expose function to load in data
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private CompoundTag tryRead(ChunkPos pos) {
|
private CompoundTag tryRead(ChunkPos pos) {
|
||||||
try {
|
try {
|
||||||
@ -3577,9 +3545,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
} else {
|
} else {
|
||||||
LOGGER.error("Expected compound tag, got {}", (Object)tag);
|
LOGGER.error("Expected compound tag, got {}", (Object)tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ // Paper start - internal get data function, copied from above
|
+ // Paper start - internal get data function, copied from above
|
||||||
+ private CompoundTag getDataInternal(ChunkPos chunkcoordintpair) {
|
+ private CompoundTag getDataInternal(ChunkPos chunkcoordintpair) {
|
||||||
+ Dynamic<Tag> dynamic = this.writeColumn(chunkcoordintpair, NbtOps.INSTANCE);
|
+ Dynamic<Tag> dynamic = this.writeColumn(chunkcoordintpair, NbtOps.INSTANCE);
|
||||||
@ -3595,9 +3563,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||||||
+ // Paper end
|
+ // Paper end
|
||||||
private <T> Dynamic<T> writeColumn(ChunkPos chunkPos, DynamicOps<T> dynamicOps) {
|
private <T> Dynamic<T> writeColumn(ChunkPos chunkPos, DynamicOps<T> dynamicOps) {
|
||||||
Map<T, T> map = Maps.newHashMap();
|
Map<T, T> map = Maps.newHashMap();
|
||||||
|
|
||||||
@@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable {
|
@@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
- this.worker.close();
|
- this.worker.close();
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Aikar <aikar@aikar.co>
|
|
||||||
Date: Sun, 26 Aug 2018 20:49:50 -0400
|
|
||||||
Subject: [PATCH] Optimize MappedRegistry
|
|
||||||
|
|
||||||
Use larger initial sizes to increase bucket capacity on the BiMap
|
|
||||||
|
|
||||||
BiMap.get was seen to be using a good bit of CPU time.
|
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java
|
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
||||||
--- a/src/main/java/net/minecraft/core/MappedRegistry.java
|
|
||||||
+++ b/src/main/java/net/minecraft/core/MappedRegistry.java
|
|
||||||
@@ -0,0 +0,0 @@ import org.apache.logging.log4j.Logger;
|
|
||||||
public class MappedRegistry<T> extends WritableRegistry<T> {
|
|
||||||
protected static final Logger LOGGER = LogManager.getLogger();
|
|
||||||
private final ObjectList<T> byId = new ObjectArrayList<>(256);
|
|
||||||
- private final Object2IntMap<T> toId = new Object2IntOpenCustomHashMap<>(Util.identityStrategy());
|
|
||||||
+ private final it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap<T> toId = new it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap<T>(2048);// Paper - use bigger expected size to reduce collisions and direct intent for FastUtil to be identity map
|
|
||||||
private final BiMap<ResourceLocation, T> storage;
|
|
||||||
private final BiMap<ResourceKey<T>, T> keyStorage;
|
|
||||||
private final Map<T, Lifecycle> lifecycles;
|
|
||||||
@@ -0,0 +0,0 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
|
|
||||||
public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle lifecycle) {
|
|
||||||
super(key, lifecycle);
|
|
||||||
this.toId.defaultReturnValue(-1);
|
|
||||||
- this.storage = HashBiMap.create();
|
|
||||||
- this.keyStorage = HashBiMap.create();
|
|
||||||
- this.lifecycles = Maps.newIdentityHashMap();
|
|
||||||
+ this.storage = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
|
|
||||||
+ this.keyStorage = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
|
|
||||||
+ this.lifecycles = new java.util.IdentityHashMap<>(2048); // Paper - use bigger expected size to reduce collisions
|
|
||||||
this.elementsLifecycle = lifecycle;
|
|
||||||
}
|
|
||||||
|
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren