From 1f9c72d0936cf6efd64c8c0bd37d4af1c4d677e4 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Sat, 9 Nov 2024 13:57:44 +0100 Subject: [PATCH] fix compile --- .../com/volmit/iris/core/IrisSettings.java | 28 ++++++- .../iris/core/pregenerator/ChunkUpdater.java | 48 +++-------- .../volmit/iris/util/profile/MsptTimings.java | 84 +++++++++++++++++++ 3 files changed, 120 insertions(+), 40 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/util/profile/MsptTimings.java diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index e4257d250..8a687b564 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -25,7 +25,9 @@ import com.volmit.iris.util.json.JSONException; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.scheduling.ChronoLatch; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import java.io.File; import java.io.IOException; @@ -42,6 +44,7 @@ public class IrisSettings { private IrisSettingsConcurrency concurrency = new IrisSettingsConcurrency(); private IrisSettingsStudio studio = new IrisSettingsStudio(); private IrisSettingsPerformance performance = new IrisSettingsPerformance(); + private IrisSettingsUpdater updater = new IrisSettingsUpdater(); public static int getThreadCount(int c) { return switch (c) { @@ -142,11 +145,30 @@ public class IrisSettings { public int resourceLoaderCacheSize = 1_024; public int objectLoaderCacheSize = 4_096; public int scriptLoaderCacheSize = 512; - public double updaterThreadMultiplier = 1.0; + } - public double getUpdaterThreadMultiplier() { - return Math.min(Math.abs(updaterThreadMultiplier), 0.1); + @Data + public static class IrisSettingsUpdater { + public double threadMultiplier = 2; + public double chunkLoadSensitivity = 0.7; + public MsRange emptyMsRange = new MsRange(80, 100); + public MsRange defaultMsRange = new MsRange(20, 40); + + public double getThreadMultiplier() { + return Math.min(Math.abs(threadMultiplier), 0.1); } + + public double getChunkLoadSensitivity() { + return Math.min(chunkLoadSensitivity, 0.9); + } + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class MsRange { + public int min = 20; + public int max = 40; } @Data diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java index b42b21dab..b7d90ed95 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java @@ -12,9 +12,9 @@ import com.volmit.iris.util.mantle.MantleFlag; import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.RollingSequence; +import com.volmit.iris.util.profile.LoadBalancer; import com.volmit.iris.util.scheduling.J; import io.papermc.lib.PaperLib; -import lombok.Data; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; @@ -36,10 +36,11 @@ public class ChunkUpdater { private final AtomicInteger chunksProcessed = new AtomicInteger(); private final AtomicInteger chunksProcessedLast = new AtomicInteger(); private final AtomicInteger chunksUpdated = new AtomicInteger(); + private final AtomicBoolean serverEmpty = new AtomicBoolean(true); private final AtomicLong lastCpsTime = new AtomicLong(M.ms()); - private final int coreLimit = (int) Math.max(Runtime.getRuntime().availableProcessors() * getProperty(), 1); + private final int coreLimit = (int) Math.max(Runtime.getRuntime().availableProcessors() * IrisSettings.get().getUpdater().getThreadMultiplier(), 1); private final Semaphore semaphore = new Semaphore(256); - private final PlayerCounter playerCounter = new PlayerCounter(semaphore, 256); + private final LoadBalancer loadBalancer = new LoadBalancer(semaphore, 256, IrisSettings.get().getUpdater().emptyMsRange); private final AtomicLong startTime = new AtomicLong(); private final Dimensions dimensions; private final PregenTask task; @@ -111,7 +112,12 @@ public class ChunkUpdater { } }, 0, 3, TimeUnit.SECONDS); scheduler.scheduleAtFixedRate(this::unloadChunks, 0, 1, TimeUnit.SECONDS); - scheduler.scheduleAtFixedRate(playerCounter::update, 0, 5, TimeUnit.SECONDS); + scheduler.scheduleAtFixedRate(() -> { + boolean empty = Bukkit.getOnlinePlayers().isEmpty(); + if (serverEmpty.getAndSet(empty) == empty) + return; + loadBalancer.setRange(empty ? IrisSettings.get().getUpdater().emptyMsRange : IrisSettings.get().getUpdater().defaultMsRange); + }, 0, 10, TimeUnit.SECONDS); var t = new Thread(() -> { run(); @@ -127,7 +133,7 @@ public class ChunkUpdater { public void close() { try { - playerCounter.close(); + loadBalancer.close(); semaphore.acquire(256); executor.shutdown(); @@ -343,36 +349,4 @@ public class ChunkUpdater { } private record Dimensions(Position2 min, Position2 max, int count, PregenTask task) { } - - @Data - private static class PlayerCounter { - private final Semaphore semaphore; - private final int maxPermits; - private int lastCount = 0; - private int permits = 0; - - public void update() { - double count = Bukkit.getOnlinePlayers().size(); - if (count == lastCount) - return; - double p = count == 0 ? 0 : count / (Bukkit.getMaxPlayers() / 2d); - int targetPermits = (int) (maxPermits * p); - - int diff = targetPermits - permits; - permits = targetPermits; - lastCount = (int) count; - try { - if (diff > 0) semaphore.release(diff); - else semaphore.acquire(Math.abs(diff)); - } catch (InterruptedException ignored) {} - } - - public void close() { - semaphore.release(permits); - } - } - - private static double getProperty() { - return IrisSettings.get().getPerformance().getUpdaterThreadMultiplier(); - } } diff --git a/core/src/main/java/com/volmit/iris/util/profile/MsptTimings.java b/core/src/main/java/com/volmit/iris/util/profile/MsptTimings.java new file mode 100644 index 000000000..2d098e1e7 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/profile/MsptTimings.java @@ -0,0 +1,84 @@ +package com.volmit.iris.util.profile; + +import com.volmit.iris.util.math.M; +import com.volmit.iris.util.scheduling.J; +import com.volmit.iris.util.scheduling.Looper; +import org.bukkit.Bukkit; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; + +public abstract class MsptTimings extends Looper { + private final AtomicInteger currentTick = new AtomicInteger(0); + private int lastTick, lastMspt; + private long lastTime; + private int taskId = -1; + + public MsptTimings() { + setName("MsptTimings"); + setPriority(9); + setDaemon(true); + } + + public static MsptTimings of(Consumer update) { + return new Simple(update); + } + + @Override + protected final long loop() { + if (startTickTask()) + return 200; + + long now = M.ms(); + int tick = currentTick.get(); + int deltaTick = tick - lastTick; + if (deltaTick == 0) + return 200; + lastTick = tick; + int deltaTime = (int) (now - lastTime); + lastTime = now; + int mspt = deltaTime / deltaTick; + mspt -= 50; + mspt = Math.max(mspt, 0); + lastMspt = mspt; + update(mspt); + return 200; + } + + public final int getMspt() { + return lastMspt; + } + + protected abstract void update(int mspt); + + private boolean startTickTask() { + if (taskId != -1 && (Bukkit.getScheduler().isQueued(taskId) || Bukkit.getScheduler().isCurrentlyRunning(taskId))) + return false; + + taskId = J.sr(() -> { + if (isInterrupted()) { + J.csr(taskId); + return; + } + + currentTick.incrementAndGet(); + }, 1); + return taskId != -1; + } + + private static class Simple extends MsptTimings { + private final Consumer update; + + private Simple(Consumer update) { + this.update = update; + start(); + } + + @Override + protected void update(int mspt) { + if (update == null) + return; + update.accept(mspt); + } + } +}