2021-05-14 20:53:43 +02:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: ishland <ishlandmc@yeah.net>
Date: Fri, 5 Feb 2021 19:34:00 +0800
Subject: [PATCH] Multi-threaded World Upgrade
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
2021-05-27 19:22:44 +02:00
index 15b972b4a93b8fe3655acec47bc84b0f2c4620a6..67fdde82b7bff1b4973542acc4fe0d72f706d87e 100644
2021-05-14 20:53:43 +02:00
--- a/src/main/java/net/minecraft/server/Main.java
+++ b/src/main/java/net/minecraft/server/Main.java
2021-05-27 19:22:44 +02:00
@@ -292,6 +292,8 @@ public class Main {
2021-05-14 20:53:43 +02:00
WorldUpgrader worldupgrader = new WorldUpgrader(convertable_conversionsession, datafixer, immutableset, flag);
IChatBaseComponent ichatbasecomponent = null;
+ long lastLocation = 0L; // Yatopia
+ long lastTime = System.nanoTime(); // Yatopia
while (!worldupgrader.b()) {
IChatBaseComponent ichatbasecomponent1 = worldupgrader.h();
2021-05-27 19:22:44 +02:00
@@ -300,13 +302,16 @@ public class Main {
2021-05-14 20:53:43 +02:00
Main.LOGGER.info(worldupgrader.h().getString());
}
- int i = worldupgrader.e();
-
- if (i > 0) {
- int j = worldupgrader.f() + worldupgrader.g();
-
- Main.LOGGER.info("{}% completed ({} / {} chunks)...", MathHelper.d((float) j / (float) i * 100.0F), j, i);
- }
+ // Yatopia start
+ long totalChunkCount = worldupgrader.getTotalChunkCount();
+ if (totalChunkCount > 0) {
+ long processedCount = worldupgrader.getUpgradedChunkCount() + worldupgrader.getSkippedChunkCount();
+ long currentTime = System.nanoTime();
+ String speedRate = String.format("%.1f", (processedCount - lastLocation) / ((currentTime - lastTime) / 1_000_000_000.0));
+ Main.LOGGER.info("{}% completed ({} / {} chunks) at {}cps...", MathHelper.d((float) processedCount / (float) totalChunkCount * 100.0F), processedCount, totalChunkCount, speedRate);
+ lastLocation = processedCount;
+ lastTime = currentTime;
+ } // Yatopia end
if (!booleansupplier.getAsBoolean()) {
worldupgrader.a();
diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
2021-05-27 19:22:44 +02:00
index cb394ec310712cc97d65afe068284b277d7f0483..12370f64b3590faabeef6e03db09a57bc87bc2ef 100644
2021-05-14 20:53:43 +02:00
--- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
+++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
@@ -33,6 +33,13 @@ import net.minecraft.world.level.storage.Convertable;
import net.minecraft.world.level.storage.WorldPersistentData;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+// Yatopia start
+import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+// Yatopia end
// CraftBukkit start
import net.minecraft.world.level.dimension.DimensionManager;
@@ -50,9 +57,9 @@ public class WorldUpgrader {
private volatile boolean h = true;
private volatile boolean i;
private volatile float j;
- private volatile int k;
- private volatile int l;
- private volatile int m;
+ private volatile long k; // Yatopia - int -> long
+ private volatile long l; // Yatopia - int -> long
+ private volatile long m; // Yatopia - int -> long
private final Object2FloatMap<ResourceKey<DimensionManager>> n = Object2FloatMaps.synchronize(new Object2FloatOpenCustomHashMap(SystemUtils.k())); // CraftBukkit
private volatile IChatBaseComponent o = new ChatMessage("optimizeWorld.stage.counting");
2021-05-27 19:22:44 +02:00
private static final Pattern p = Pattern.compile("^r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.mca$"); public static final Pattern getRegionfileRegex() { return p; } // Paper - OBFHELPER
2021-05-14 20:53:43 +02:00
@@ -117,6 +124,11 @@ public class WorldUpgrader {
this.o = new ChatMessage("optimizeWorld.stage.upgrading");
+ // Yatopia start
+ final ExecutorService upgradeExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactoryBuilder().setDaemon(true).setPriority(Thread.NORM_PRIORITY - 1).setNameFormat("WorldUpgrader Worker #%d").build());
+ final Set<CompletableFuture<Void>> futures = new ObjectOpenHashSet<>();
+ final com.ibm.asyncutil.locks.AsyncNamedLock<Integer> regionFileLocks = com.ibm.asyncutil.locks.AsyncNamedLock.createFair();
+ // Yatopia end
while (this.h) {
boolean flag = false;
float f1 = 0.0F;
@@ -130,6 +142,11 @@ public class WorldUpgrader {
if (listiterator.hasNext()) {
ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) listiterator.next();
+ // Yatopia start
+ flag = true;
+ futures.add(regionFileLocks.acquireLock(String.format("%d %d", chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()).hashCode()).toCompletableFuture().thenAcceptAsync(lockToken -> {
+ try {
+ // Yatopia end
boolean flag1 = false;
try {
@@ -179,7 +196,12 @@ public class WorldUpgrader {
++this.m;
}
- flag = true;
+ // Yatopia start
+ } finally {
+ lockToken.releaseLock();
+ }
+ }, upgradeExecutor));
+ // Yatopia end
}
f2 = (float) listiterator.nextIndex() / f;
@@ -192,6 +214,8 @@ public class WorldUpgrader {
}
}
+ CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); // Yatopia
+ upgradeExecutor.shutdown(); // Yatopia
this.o = new ChatMessage("optimizeWorld.stage.finished");
UnmodifiableIterator unmodifiableiterator3 = immutablemap1.values().iterator();
@@ -280,16 +304,19 @@ public class WorldUpgrader {
}
public int e() {
- return this.k;
+ return (int) this.k; // Yatopia
}
+ public long getTotalChunkCount() { return this.k; } // Yatopia
public int f() {
- return this.l;
+ return (int) this.l; // Yatopia
}
+ public long getUpgradedChunkCount() { return this.l; } // Yatopia
public int g() {
- return this.m;
+ return (int) this.m; // Yatopia
}
+ public long getSkippedChunkCount() { return this.m; } // Yatopia
public IChatBaseComponent h() {
return this.o;