diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index fd93d97a8..b1866351e 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -27,7 +27,6 @@ import com.volmit.iris.core.link.MultiverseCoreLink; import com.volmit.iris.core.link.MythicMobsLink; import com.volmit.iris.core.link.OraxenLink; import com.volmit.iris.core.nms.INMS; -import com.volmit.iris.core.project.IrisProject; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.engine.object.biome.IrisBiome; @@ -165,6 +164,7 @@ public class Iris extends VolmitPlugin implements Listener { HandlerList.unregisterAll((Plugin) this); postShutdown.forEach(Runnable::run); services.clear(); + MultiBurst.burst.close(); super.onDisable(); } diff --git a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java index f705d75e8..dcb5d5ee1 100644 --- a/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java +++ b/src/main/java/com/volmit/iris/core/command/studio/CommandIrisStudioUpdate.java @@ -66,7 +66,7 @@ public class CommandIrisStudioUpdate extends MortarCommand { IrisData data = IrisData.get(Iris.service(StudioSVC.class).getWorkspaceFolder(args[0])); int t = data.getObjectLoader().getPossibleKeys().length; ChronoLatch cl = new ChronoLatch(250, false); - MultiBurst bx = new MultiBurst("Object Rewriter", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors()); + MultiBurst bx = MultiBurst.burst; BurstExecutor b = bx.burst(); int g = 0; for (String f : data.getObjectLoader().getPossibleKeys()) { @@ -102,7 +102,6 @@ public class CommandIrisStudioUpdate extends MortarCommand { int finalG = g; J.a(() -> { b.complete(); - bx.shutdownNow(); sender.sendMessage("Done! Rewrote " + Form.f(finalG) + " Objects!"); }); } diff --git a/src/main/java/com/volmit/iris/core/decrees/DecStudio.java b/src/main/java/com/volmit/iris/core/decrees/DecStudio.java index 7a243f2aa..00f4f1275 100644 --- a/src/main/java/com/volmit/iris/core/decrees/DecStudio.java +++ b/src/main/java/com/volmit/iris/core/decrees/DecStudio.java @@ -133,7 +133,7 @@ public class DecStudio implements DecreeExecutor { KList jobs = new KList<>(); KList files = new KList(); files(Iris.instance.getDataFolder("packs", project.getLoadKey()), files); - MultiBurst burst = new MultiBurst("Cleaner", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors() * 2); + MultiBurst burst = MultiBurst.burst; jobs.add(new SingleJob("Updating Workspace", () -> { if (!new IrisProject(Iris.service(StudioSVC.class).getWorkspaceFolder(project.getLoadKey())).updateWorkspace()) { @@ -237,8 +237,6 @@ public class DecStudio implements DecreeExecutor { jobs.add(q); } - jobs.add(new SingleJob("Finishing Up", burst::shutdownNow)); - new JobCollection("Cleaning", jobs).execute(sender()); } diff --git a/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java index fa612adcb..36a631e17 100644 --- a/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java +++ b/src/main/java/com/volmit/iris/core/gui/NoiseExplorerGUI.java @@ -59,7 +59,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List static double ascale = 10; CNG cng = NoiseStyle.STATIC.create(new RNG(RNG.r.nextLong())); @SuppressWarnings("CanBeFinal") - MultiBurst gx = new MultiBurst("Iris Noise Renderer", Thread.MAX_PRIORITY, Runtime.getRuntime().availableProcessors()); + MultiBurst gx = MultiBurst.burst; ReentrantLock l = new ReentrantLock(); BufferedImage img; int w = 0; @@ -299,7 +299,6 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List frame.addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(java.awt.event.WindowEvent windowEvent) { - nv.gx.shutdownLater(); Iris.instance.unregisterListener(nv); } }); diff --git a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java index 43e9ca166..137a57595 100644 --- a/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java +++ b/src/main/java/com/volmit/iris/core/pregenerator/methods/AsyncPregenMethod.java @@ -41,7 +41,7 @@ public class AsyncPregenMethod implements PregeneratorMethod { } this.world = world; - burst = new MultiBurst("Iris Async Pregenerator", IrisSettings.get().getConcurrency().getPregenThreadPriority(), threads); + burst = MultiBurst.burst; future = new KList<>(1024); } @@ -92,7 +92,6 @@ public class AsyncPregenMethod implements PregeneratorMethod { @Override public void close() { waitForChunks(); - burst.shutdownAndAwait(); unloadAndSaveAllChunks(); } diff --git a/src/main/java/com/volmit/iris/core/service/PreservationSVC.java b/src/main/java/com/volmit/iris/core/service/PreservationSVC.java index 49a7a8ad0..a6ea2ac7f 100644 --- a/src/main/java/com/volmit/iris/core/service/PreservationSVC.java +++ b/src/main/java/com/volmit/iris/core/service/PreservationSVC.java @@ -31,7 +31,6 @@ import java.util.concurrent.ExecutorService; public class PreservationSVC implements IrisService { private KList threads = new KList<>(); - private KList bursts = new KList<>(); private KList services = new KList<>(); private Looper dereferencer; @@ -42,7 +41,7 @@ public class PreservationSVC implements IrisService public void register(MultiBurst burst) { - bursts.add(burst); + } public void register(ExecutorService service) @@ -94,20 +93,6 @@ public class PreservationSVC implements IrisService } } - for(MultiBurst i : bursts) - { - try - { - i.shutdownNow(); - Iris.info("Shutdown Multiburst " + i); - } - - catch(Throwable e) - { - Iris.reportError(e); - } - } - for(ExecutorService i : services) { try diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java index 250b343cb..7a7c18b4a 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineTarget.java @@ -36,9 +36,7 @@ public class EngineTarget { this.world = world; this.dimension = dimension; this.data = data; - this.burster = new MultiBurst("Iris Engine " + dimension.getName(), - IrisSettings.get().getConcurrency().getEngineThreadPriority(), - IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getEngineThreadCount())); + this.burster = MultiBurst.burst; } public int getHeight() { @@ -46,6 +44,6 @@ public class EngineTarget { } public void close() { - burster.shutdownLater(); + } } diff --git a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java index f3701efb2..4def637ca 100644 --- a/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java +++ b/src/main/java/com/volmit/iris/engine/platform/HeadlessGenerator.java @@ -58,7 +58,7 @@ public class HeadlessGenerator implements PlatformChunkGenerator { public HeadlessGenerator(HeadlessWorld world) { this.world = world; - burst = new MultiBurst("Iris Headless Generator", 9, IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getPregenThreadCount())); + burst = MultiBurst.burst; writer = new NBTWorld(world.getWorld().worldFolder()); engine = new IrisEngine(new EngineTarget(world.getWorld(), world.getDimension(), world.getDimension().getLoader()), isStudio()); } @@ -131,7 +131,6 @@ public class HeadlessGenerator implements PlatformChunkGenerator { } public void close() { - burst.shutdownAndAwait(); getEngine().close(); writer.close(); } diff --git a/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/src/main/java/com/volmit/iris/util/mantle/Mantle.java index a5ad56d6b..4d120dfae 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -80,7 +80,7 @@ public class Mantle { unload = new KSet<>(); loadedRegions = new KMap<>(); lastUse = new KMap<>(); - ioBurst = new MultiBurst("Iris Mantle[" + dataFolder.hashCode() + "]", Thread.MIN_PRIORITY, Runtime.getRuntime().availableProcessors() / 2); + ioBurst = MultiBurst.burst; Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath()); } @@ -126,6 +126,19 @@ public class Mantle { get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).flag(flag, flagged); } + /** + * Check very quickly if a tectonic plate exists via cached or the file system + * @param x the x region coordinate + * @param z the z region coordinate + * @return true if it exists + */ + @RegionCoordinates + public boolean hasTectonicPlate(int x, int z) + { + Long k = key(x, z); + return loadedRegions.containsKey(k) || fileForRegion(dataFolder, k).exists(); + } + /** * Iterate data in a chunk * @param x the chunk x @@ -137,6 +150,11 @@ public class Mantle { */ @ChunkCoordinates public void iterateChunk(int x, int z, Class type, Consumer4 iterator, MantleFlag... requiredFlags) { + if(!hasTectonicPlate(x >> 5, z >> 5)) + { + return; + } + for (MantleFlag i : requiredFlags) { if (!hasFlag(x, z, i)) { return; @@ -155,6 +173,11 @@ public class Mantle { */ @ChunkCoordinates public boolean hasFlag(int x, int z, MantleFlag flag) { + if(!hasTectonicPlate(x >> 5, z >> 5)) + { + return false; + } + return get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).isFlagged(flag); } @@ -211,7 +234,12 @@ public class Mantle { throw new RuntimeException("The Mantle is closed"); } - if (y < 0) { + if(!hasTectonicPlate(x >> 5, z >> 5)) + { + return null; + } + + if (y < 0 || y >= worldHeight) { return null; } @@ -263,7 +291,6 @@ public class Mantle { Iris.reportError(e); } - ioBurst.shutdownNow(); Iris.debug("The Mantle has Closed " + C.DARK_AQUA + dataFolder.getAbsolutePath()); } diff --git a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java index 92a07825e..d625cbe59 100644 --- a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java +++ b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java @@ -19,13 +19,9 @@ package com.volmit.iris.util.parallel; import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.service.PreservationSVC; import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.io.InstanceState; import com.volmit.iris.util.math.M; -import com.volmit.iris.util.scheduling.J; -import com.volmit.iris.util.scheduling.Looper; import java.util.List; import java.util.concurrent.*; @@ -33,66 +29,39 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.function.Supplier; public class MultiBurst { - public static final MultiBurst burst = new MultiBurst("Iris", IrisSettings.get().getConcurrency().getMiscThreadPriority(), IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getMiscThreadCount())); + public static final MultiBurst burst = new MultiBurst(); private ExecutorService service; - private final Looper heartbeat; private final AtomicLong last; - private int tid; private final String name; - private final int tc; private final int priority; - private final int instance; - public MultiBurst(int tc) { - this("Iris", 6, tc); + public MultiBurst() { + this("Iris", Thread.MIN_PRIORITY); } - public MultiBurst(String name, int priority, int tc) { + public MultiBurst(String name, int priority) { this.name = name; this.priority = priority; - this.tc = tc; - instance = InstanceState.getInstanceId(); last = new AtomicLong(M.ms()); - heartbeat = new Looper() { - @Override - protected long loop() { - if (instance != InstanceState.getInstanceId()) { - shutdownNow(); - return -1; - } - - if (M.ms() - last.get() > TimeUnit.MINUTES.toMillis(1) && service != null) { - service.shutdown(); - service = null; - Iris.debug("Shutting down MultiBurst Pool " + getName() + " to conserve resources."); - } - - return 30000; - } - }; - heartbeat.setName(name + " Monitor"); - heartbeat.start(); Iris.service(PreservationSVC.class).register(this); } private synchronized ExecutorService getService() { last.set(M.ms()); if (service == null || service.isShutdown()) { - service = Executors.newFixedThreadPool(Math.max(tc, 1), r -> { - tid++; - Thread t = new Thread(r); - t.setName(name + " " + tid); - t.setPriority(priority); - t.setUncaughtExceptionHandler((et, e) -> - { - Iris.info("Exception encountered in " + et.getName()); - e.printStackTrace(); - }); + service = new ForkJoinPool(Runtime.getRuntime().availableProcessors(), + new ForkJoinPool.ForkJoinWorkerThreadFactory() { + int m = 0; - return t; - }); - Iris.service(PreservationSVC.class).register(service); - Iris.debug("Started MultiBurst Pool " + name + " with " + tc + " threads at " + priority + " priority."); + @Override + public ForkJoinWorkerThread newThread(ForkJoinPool pool) { + final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool); + worker.setPriority(priority); + worker.setName(name + " " + ++m); + return worker; + } + }, + (t, e) -> e.printStackTrace(), true); } return service; @@ -146,56 +115,7 @@ public class MultiBurst { return CompletableFuture.supplyAsync(o, getService()); } - public void shutdownNow() { - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - heartbeat.interrupt(); - - if (service != null) { - service.shutdownNow().forEach(Runnable::run); - } - } - - public void shutdown() { - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - heartbeat.interrupt(); - - if (service != null) { - service.shutdown(); - } - } - - public void shutdownLater() { - if (service != null) { - try - { - service.submit(() -> { - J.sleep(3000); - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - - if (service != null) { - service.shutdown(); - } - }); - - heartbeat.interrupt(); - } - - catch(Throwable e) - { - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - - if (service != null) { - service.shutdown(); - } - - heartbeat.interrupt(); - } - } - } - - public void shutdownAndAwait() { - Iris.debug("Shutting down MultiBurst Pool " + heartbeat.getName() + "."); - heartbeat.interrupt(); + public void close() { if (service != null) { service.shutdown(); try {