From f5f4c5c6727309289f329d7b04fa1e75a8046d84 Mon Sep 17 00:00:00 2001 From: cyberpwn Date: Thu, 19 Aug 2021 03:26:45 -0400 Subject: [PATCH] Performance improvements --- .../com/volmit/iris/engine/IrisEngine.java | 4 +- .../engine/actuator/IrisBiomeActuator.java | 54 ++++---- .../engine/actuator/IrisDecorantActuator.java | 118 +++++++++--------- .../engine/framework/EngineComponent.java | 6 + .../iris/engine/mantle/EngineMantle.java | 16 ++- .../engine/modifier/IrisDepositModifier.java | 18 ++- .../engine/modifier/IrisPostModifier.java | 35 ++++-- .../java/com/volmit/iris/util/hunk/Hunk.java | 5 + .../com/volmit/iris/util/mantle/Mantle.java | 11 ++ .../volmit/iris/util/mantle/MantleChunk.java | 22 ++++ .../iris/util/parallel/BurstExecutor.java | 39 ++++++ .../volmit/iris/util/parallel/MultiBurst.java | 7 ++ 12 files changed, 238 insertions(+), 97 deletions(-) diff --git a/src/main/java/com/volmit/iris/engine/IrisEngine.java b/src/main/java/com/volmit/iris/engine/IrisEngine.java index 5bea6a8dc..0e6fdff5e 100644 --- a/src/main/java/com/volmit/iris/engine/IrisEngine.java +++ b/src/main/java/com/volmit/iris/engine/IrisEngine.java @@ -412,14 +412,14 @@ public class IrisEngine extends BlockPopulator implements Engine { switch (getDimension().getTerrainMode()) { case NORMAL -> { - getMantle().generateMatter(x >> 4, z >> 4); + getMantle().generateMatter(x >> 4, z >> 4, multicore); getTerrainActuator().actuate(x, z, vblocks, multicore); getBiomeActuator().actuate(x, z, vbiomes, multicore); getCaveModifier().modify(x, z, vblocks, multicore); getRavineModifier().modify(x, z, vblocks, multicore); getPostModifier().modify(x, z, vblocks, multicore); getDecorantActuator().actuate(x, z, blocks, multicore); - getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks); + getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore); getDepositModifier().modify(x, z, blocks, multicore); } case ISLANDS -> { diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java index b78f27264..45b8fd31c 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisBiomeActuator.java @@ -26,9 +26,12 @@ import com.volmit.iris.engine.framework.EngineAssignedActuator; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.biome.IrisBiomeCustom; import com.volmit.iris.util.documentation.BlockCoordinates; +import com.volmit.iris.util.format.Form; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.hunk.view.BiomeGridHunkView; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.parallel.BurstExecutor; +import com.volmit.iris.util.parallel.MultiBurst; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import org.bukkit.block.Biome; import org.bukkit.generator.ChunkGenerator; @@ -65,41 +68,46 @@ public class IrisBiomeActuator extends EngineAssignedActuator { @Override public void onActuate(int x, int z, Hunk h, boolean multicore) { PrecisionStopwatch p = PrecisionStopwatch.start(); - int zf, maxHeight; - IrisBiome ib; + BurstExecutor burst = burst().burst(); + burst.setMulticore(multicore); for (int xf = 0; xf < h.getWidth(); xf++) { - for (zf = 0; zf < h.getDepth(); zf++) { - ib = getComplex().getTrueBiomeStream().get(modX(xf + x), modZ(zf + z)); - maxHeight = (int) (getComplex().getFluidHeight() + ib.getMaxWithObjectHeight(getData())); - if (ib.isCustom()) { - try { - IrisBiomeCustom custom = ib.getCustomBiome(rng, x, 0, z); - Object biomeBase = INMS.get().getCustomBiomeBaseFor(getDimension().getLoadKey() + ":" + custom.getId()); + int finalXf = xf; + burst.queue(() -> { + IrisBiome ib; + for (int zf = 0; zf < h.getDepth(); zf++) { + ib = getComplex().getTrueBiomeStream().get(modX(finalXf + x), modZ(zf + z)); + int maxHeight = (int) (getComplex().getFluidHeight() + ib.getMaxWithObjectHeight(getData())); + if (ib.isCustom()) { + try { + IrisBiomeCustom custom = ib.getCustomBiome(rng, x, 0, z); + Object biomeBase = INMS.get().getCustomBiomeBaseFor(getDimension().getLoadKey() + ":" + custom.getId()); - if (biomeBase == null || !injectBiome(h, x, 0, z, biomeBase)) { - throw new RuntimeException("Cant inject biome!"); - } + if (biomeBase == null || !injectBiome(h, x, 0, z, biomeBase)) { + throw new RuntimeException("Cant inject biome!"); + } - for (int i = 0; i < maxHeight; i++) { - injectBiome(h, xf, i, zf, biomeBase); + for (int i = 0; i < maxHeight; i++) { + injectBiome(h, finalXf, i, zf, biomeBase); + } + } catch (Throwable e) { + Iris.reportError(e); + Biome v = ib.getSkyBiome(rng, x, 0, z); + for (int i = 0; i < maxHeight; i++) { + h.set(finalXf, i, zf, v); + } } - } catch (Throwable e) { - Iris.reportError(e); + } else { Biome v = ib.getSkyBiome(rng, x, 0, z); for (int i = 0; i < maxHeight; i++) { - h.set(xf, i, zf, v); + h.set(finalXf, i, zf, v); } } - } else { - Biome v = ib.getSkyBiome(rng, x, 0, z); - for (int i = 0; i < maxHeight; i++) { - h.set(xf, i, zf, v); - } } - } + }); } + burst.complete(); getEngine().getMetrics().getBiome().put(p.getMilliseconds()); } } diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java index 000c4ff5e..744f30048 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisDecorantActuator.java @@ -23,19 +23,19 @@ import com.volmit.iris.engine.decorator.*; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineAssignedActuator; import com.volmit.iris.engine.framework.EngineDecorator; -import com.volmit.iris.engine.object.biome.InferredType; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.carve.IrisCaveLayer; -import com.volmit.iris.engine.object.decoration.IrisDecorationPart; -import com.volmit.iris.engine.object.decoration.IrisDecorator; import com.volmit.iris.util.documentation.BlockCoordinates; +import com.volmit.iris.util.format.Form; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import lombok.Getter; import org.bukkit.Material; import org.bukkit.block.data.BlockData; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiPredicate; import java.util.function.Predicate; @@ -90,76 +90,82 @@ public class IrisDecorantActuator extends EngineAssignedActuator { } PrecisionStopwatch p = PrecisionStopwatch.start(); - - int j, realX, realZ, height; - IrisBiome biome, cave; - + BurstExecutor burst = burst().burst(); + burst.setMulticore(multicore); for (int i = 0; i < output.getWidth(); i++) { - for (j = 0; j < output.getDepth(); j++) { - boolean solid, liquid; - int emptyFor = 0; - int liquidFor = 0; - int lastSolid = 0; - realX = (int) Math.round(modX(x + i)); - realZ = (int) Math.round(modZ(z + j)); - height = (int) Math.round(getComplex().getHeightStream().get(realX, realZ)); - biome = getComplex().getTrueBiomeStream().get(realX, realZ); - cave = shouldRay ? getComplex().getCaveBiomeStream().get(realX, realZ) : null; + int finalI = i; + burst.queue(() -> { + int height; + int realX = (int) Math.round(modX(x + finalI)); + int realZ; + IrisBiome biome, cave; + for (int j=0; j < output.getDepth(); j++) { + boolean solid, liquid; + int emptyFor = 0; + int liquidFor = 0; + int lastSolid = 0; + realZ = (int) Math.round(modZ(z + j)); + height = (int) Math.round(getComplex().getHeightStream().get(realX, realZ)); + biome = getComplex().getTrueBiomeStream().get(realX, realZ); + cave = shouldRay ? getComplex().getCaveBiomeStream().get(realX, realZ) : null; - if (biome.getDecorators().isEmpty() && (cave == null || cave.getDecorators().isEmpty())) { - continue; - } + if (biome.getDecorators().isEmpty() && (cave == null || cave.getDecorators().isEmpty())) { + continue; + } - if(height < getDimension().getFluidHeight()) - { - getSeaSurfaceDecorator().decorate(i, j, - realX, (int) Math.round(modX(x + i + 1)), (int) Math.round(modX(x + i - 1)), - realZ, (int) Math.round(modZ(z + j + 1)), (int) Math.round(modZ(z + j - 1)), - output, biome, getDimension().getFluidHeight(), getEngine().getHeight()); - getSeaFloorDecorator().decorate(i, j, - realX, realZ, output, biome, height + 1, - getDimension().getFluidHeight() + 1); - } + if(height < getDimension().getFluidHeight()) + { + getSeaSurfaceDecorator().decorate(finalI, j, + realX, (int) Math.round(modX(x + finalI + 1)), (int) Math.round(modX(x + finalI - 1)), + realZ, (int) Math.round(modZ(z + j + 1)), (int) Math.round(modZ(z + j - 1)), + output, biome, getDimension().getFluidHeight(), getEngine().getHeight()); + getSeaFloorDecorator().decorate(finalI, j, + realX, realZ, output, biome, height + 1, + getDimension().getFluidHeight() + 1); + } - if (height == getDimension().getFluidHeight()) { - getShoreLineDecorator().decorate(i, j, - realX, (int) Math.round(modX(x + i + 1)), (int) Math.round(modX(x + i - 1)), - realZ, (int) Math.round(modZ(z + j + 1)), (int) Math.round(modZ(z + j - 1)), - output, biome, height, getEngine().getHeight()); - } + if (height == getDimension().getFluidHeight()) { + getShoreLineDecorator().decorate(finalI, j, + realX, (int) Math.round(modX(x + finalI + 1)), (int) Math.round(modX(x + finalI - 1)), + realZ, (int) Math.round(modZ(z + j + 1)), (int) Math.round(modZ(z + j - 1)), + output, biome, height, getEngine().getHeight()); + } - getSurfaceDecorator().decorate(i, j, realX, realZ, output, biome, height, getEngine().getHeight() - height); + getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, biome, height, getEngine().getHeight() - height); - if (cave != null && cave.getDecorators().isNotEmpty()) { - for (int k = height; k > 0; k--) { - solid = PREDICATE_SOLID.test(output.get(i, k, j)); - liquid = PREDICATE_CAVELIQUID.test(output.get(i, k + 1, j), k + 1); + if (cave != null && cave.getDecorators().isNotEmpty()) { + for (int k = height; k > 0; k--) { + solid = PREDICATE_SOLID.test(output.get(finalI, k, j)); + liquid = PREDICATE_CAVELIQUID.test(output.get(finalI, k + 1, j), k + 1); - if (solid) { - if (emptyFor > 0) { - if (liquid) { - getSeaFloorDecorator().decorate(i, j, realX, realZ, output, cave, k + 1, liquidFor + lastSolid - emptyFor + 1); - getSeaSurfaceDecorator().decorate(i, j, realX, realZ, output, cave, k + liquidFor + 1, emptyFor - liquidFor + lastSolid); - } else { - getSurfaceDecorator().decorate(i, j, realX, realZ, output, cave, k, lastSolid); - getCeilingDecorator().decorate(i, j, realX, realZ, output, cave, lastSolid - 1, emptyFor); + if (solid) { + if (emptyFor > 0) { + if (liquid) { + getSeaFloorDecorator().decorate(finalI, j, realX, realZ, output, cave, k + 1, liquidFor + lastSolid - emptyFor + 1); + getSeaSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k + liquidFor + 1, emptyFor - liquidFor + lastSolid); + } else { + getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k, lastSolid); + getCeilingDecorator().decorate(finalI, j, realX, realZ, output, cave, lastSolid - 1, emptyFor); + } + emptyFor = 0; + liquidFor = 0; } - emptyFor = 0; - liquidFor = 0; + lastSolid = k; + } else { + emptyFor++; + if (liquid) liquidFor++; } - lastSolid = k; - } else { - emptyFor++; - if (liquid) liquidFor++; } } } - } + }); } + burst.complete(); getEngine().getMetrics().getDecoration().put(p.getMilliseconds()); + } private boolean shouldRayDecorate() { diff --git a/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java b/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java index 389f52910..fb4b0a1af 100644 --- a/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java +++ b/src/main/java/com/volmit/iris/engine/framework/EngineComponent.java @@ -23,6 +23,7 @@ import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.engine.IrisComplex; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.util.math.RollingSequence; +import com.volmit.iris.util.parallel.MultiBurst; import org.bukkit.event.Listener; public interface EngineComponent { @@ -32,6 +33,11 @@ public interface EngineComponent { String getName(); + default MultiBurst burst() + { + return getEngine().burst(); + } + default void close() { try { if (this instanceof Listener) { diff --git a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index 37d34a44f..3046f8d3c 100644 --- a/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -184,7 +184,7 @@ public interface EngineMantle extends IObjectPlacer { @ChunkCoordinates - default void generateMatter(int x, int z) { + default void generateMatter(int x, int z, boolean multicore) { if (!getEngine().getDimension().isUseMantle()) { return; } @@ -199,6 +199,7 @@ public interface EngineMantle extends IObjectPlacer { }; int s = getRealRadius(); BurstExecutor burst = burst().burst(); + burst.setMulticore(multicore); for (int i = -s; i <= s; i++) { int xx = i + x; @@ -216,7 +217,16 @@ public interface EngineMantle extends IObjectPlacer { { KList px = post.copy(); post.clear(); - burst().burst(px); + + if(multicore) + { + burst().burst(px); + } + + else + { + burst().sync(px); + } } } @@ -225,7 +235,7 @@ public interface EngineMantle extends IObjectPlacer { } @ChunkCoordinates - default void insertMatter(int x, int z, Class t, Hunk blocks) { + default void insertMatter(int x, int z, Class t, Hunk blocks, boolean multicore) { if (!getEngine().getDimension().isUseMantle()) { return; } diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java index 2bf4694e2..c3402d5d6 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisDepositModifier.java @@ -18,6 +18,7 @@ package com.volmit.iris.engine.modifier; +import com.volmit.iris.Iris; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineAssignedModifier; import com.volmit.iris.engine.object.biome.IrisBiome; @@ -25,8 +26,11 @@ import com.volmit.iris.engine.object.deposits.IrisDepositGenerator; import com.volmit.iris.engine.object.objects.IrisObject; import com.volmit.iris.engine.object.regional.IrisRegion; import com.volmit.iris.util.data.HeightMap; +import com.volmit.iris.util.format.Form; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.parallel.BurstExecutor; +import com.volmit.iris.util.parallel.MultiBurst; import com.volmit.iris.util.scheduling.PrecisionStopwatch; import org.bukkit.block.data.BlockData; import org.bukkit.util.BlockVector; @@ -42,30 +46,32 @@ public class IrisDepositModifier extends EngineAssignedModifier { @Override public void onModify(int x, int z, Hunk output, boolean multicore) { PrecisionStopwatch p = PrecisionStopwatch.start(); - generateDeposits(rng, output, Math.floorDiv(x, 16), Math.floorDiv(z, 16)); + generateDeposits(rng, output, Math.floorDiv(x, 16), Math.floorDiv(z, 16), multicore); getEngine().getMetrics().getDeposit().put(p.getMilliseconds()); } - public void generateDeposits(RNG rx, Hunk terrain, int x, int z) { + public void generateDeposits(RNG rx, Hunk terrain, int x, int z, boolean multicore) { RNG ro = rx.nextParallelRNG(x * x).nextParallelRNG(z * z); IrisRegion region = getComplex().getRegionStream().get((x * 16) + 7, (z * 16) + 7); IrisBiome biome = getComplex().getTrueBiomeStream().get((x * 16) + 7, (z * 16) + 7); - + BurstExecutor burst = burst().burst(); + burst.setMulticore(multicore); for (IrisDepositGenerator k : getDimension().getDeposits()) { - generate(k, terrain, ro, x, z, false); + burst.queue(() -> generate(k, terrain, ro, x, z, false)); } for (IrisDepositGenerator k : region.getDeposits()) { for (int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) { - generate(k, terrain, ro, x, z, false); + burst.queue(() -> generate(k, terrain, ro, x, z, false)); } } for (IrisDepositGenerator k : biome.getDeposits()) { for (int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) { - generate(k, terrain, ro, x, z, false); + burst.queue(() -> generate(k, terrain, ro, x, z, false)); } } + burst.complete(); } public void generate(IrisDepositGenerator k, Hunk data, RNG rng, int cx, int cz, boolean safe) { diff --git a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java index d2a5bd818..fee01f68a 100644 --- a/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java +++ b/src/main/java/com/volmit/iris/engine/modifier/IrisPostModifier.java @@ -19,14 +19,26 @@ package com.volmit.iris.engine.modifier; import com.volmit.iris.Iris; +import com.volmit.iris.engine.data.cache.AtomicCache; +import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineAssignedModifier; import com.volmit.iris.engine.object.biome.IrisBiome; import com.volmit.iris.engine.object.common.CaveResult; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.data.B; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.function.*; import com.volmit.iris.util.hunk.Hunk; +import com.volmit.iris.util.hunk.storage.ArrayHunk; +import com.volmit.iris.util.math.Average; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.math.RollingSequence; +import com.volmit.iris.util.parallel.BurstExecutor; import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import com.volmit.iris.util.stream.ProceduralStream; +import com.volmit.iris.util.stream.interpolation.Interpolated; import org.bukkit.Material; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Levelled; @@ -34,9 +46,11 @@ import org.bukkit.block.data.Waterlogged; import org.bukkit.block.data.type.Slab; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.function.Supplier; public class IrisPostModifier extends EngineAssignedModifier { - private static final BlockData AIR = B.get("CAVE_AIR"); + private static final BlockData AIR = B.get("AIR"); private static final BlockData WATER = B.get("WATER"); private final RNG rng; @@ -48,15 +62,22 @@ public class IrisPostModifier extends EngineAssignedModifier { @Override public void onModify(int x, int z, Hunk output, boolean multicore) { PrecisionStopwatch p = PrecisionStopwatch.start(); - int i; + AtomicInteger i = new AtomicInteger(); AtomicInteger j = new AtomicInteger(); - - for (i = 0; i < output.getWidth(); i++) { - for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) { - post(i, j.get(), output, i + x, j.get() + z); - } + BurstExecutor burst = burst().burst(); + burst.setMulticore(multicore); + Hunk sync = output.synchronize(); + for (i.set(0); i.get() < output.getWidth(); i.getAndIncrement()) { + burst.queue(() -> { + for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) { + int ii = i.get(); + int jj = j.get(); + post(ii, jj, sync, ii + x, jj + z); + } + }); } + burst.complete(); getEngine().getMetrics().getPost().put(p.getMilliseconds()); } diff --git a/src/main/java/com/volmit/iris/util/hunk/Hunk.java b/src/main/java/com/volmit/iris/util/hunk/Hunk.java index e81c9673c..291b2b0e1 100644 --- a/src/main/java/com/volmit/iris/util/hunk/Hunk.java +++ b/src/main/java/com/volmit/iris/util/hunk/Hunk.java @@ -1449,4 +1449,9 @@ public interface Hunk { default boolean isEmpty() { return false; } + + default boolean contains(int x, int y, int z) + { + return x < getWidth() && x >= 0 && y < getHeight() && y >= 0 && z < getDepth() && z >= 0; + } } 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 256d68cb1..06a8a8e4c 100644 --- a/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -111,6 +111,17 @@ public class Mantle { get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator); } + @ChunkCoordinates + public void iterateChunk(int x, int z, Class type, Consumer4 iterator, BurstExecutor e, MantleFlag... requiredFlags) { + for (MantleFlag i : requiredFlags) { + if (!hasFlag(x, z, i)) { + return; + } + } + + get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator, e); + } + @ChunkCoordinates public boolean hasFlag(int x, int z, MantleFlag flag) { return get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).isFlagged(flag); diff --git a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java index ba3940d2a..85d248508 100644 --- a/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java +++ b/src/main/java/com/volmit/iris/util/mantle/MantleChunk.java @@ -23,6 +23,8 @@ import com.volmit.iris.util.function.Consumer4; import com.volmit.iris.util.matter.IrisMatter; import com.volmit.iris.util.matter.Matter; import com.volmit.iris.util.matter.MatterSlice; +import com.volmit.iris.util.parallel.BurstExecutor; +import com.volmit.iris.util.parallel.MultiBurst; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -184,6 +186,26 @@ public class MantleChunk { } } + public void iterate(Class type, Consumer4 iterator, BurstExecutor burst) { + for (int i = 0; i < sections.length(); i++) { + int finalI = i; + burst.queue(() -> { + int bs = (finalI << 4); + Matter matter = get(finalI); + + if (matter != null) { + MatterSlice t = matter.getSlice(type); + + if (t != null) { + t.iterateSync((a, b, c, f) -> iterator.accept(a, b + bs, c, f)); + } + } + }); + } + + burst.complete(); + } + public void iterate(Class type, Consumer4 iterator) { for (int i = 0; i < sections.length(); i++) { int bs = (i << 4); diff --git a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java index 2dfc6b6aa..ef6935a97 100644 --- a/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java +++ b/src/main/java/com/volmit/iris/util/parallel/BurstExecutor.java @@ -20,6 +20,7 @@ package com.volmit.iris.util.parallel; import com.volmit.iris.Iris; import com.volmit.iris.util.collection.KList; +import lombok.Setter; import java.util.List; import java.util.concurrent.*; @@ -28,6 +29,8 @@ import java.util.concurrent.*; public class BurstExecutor { private final ExecutorService executor; private final KList> futures; + @Setter + private boolean multicore = true; public BurstExecutor(ExecutorService executor, int burstSizeEstimate) { this.executor = executor; @@ -36,6 +39,12 @@ public class BurstExecutor { @SuppressWarnings("UnusedReturnValue") public CompletableFuture queue(Runnable r) { + if(!multicore) + { + r.run(); + return null; + } + synchronized (futures) { CompletableFuture c = CompletableFuture.runAsync(r, executor); futures.add(c); @@ -44,6 +53,16 @@ public class BurstExecutor { } public BurstExecutor queue(List r) { + if(!multicore) + { + for(Runnable i : r) + { + i.run(); + } + + return this; + } + synchronized (futures) { for (Runnable i : new KList<>(r)) { CompletableFuture c = CompletableFuture.runAsync(i, executor); @@ -55,6 +74,16 @@ public class BurstExecutor { } public BurstExecutor queue(Runnable[] r) { + if(!multicore) + { + for(Runnable i : r) + { + i.run(); + } + + return this; + } + synchronized (futures) { for (Runnable i : r) { CompletableFuture c = CompletableFuture.runAsync(i, executor); @@ -66,6 +95,11 @@ public class BurstExecutor { } public void complete() { + if(!multicore) + { + return; + } + synchronized (futures) { if (futures.isEmpty()) { return; @@ -81,6 +115,11 @@ public class BurstExecutor { } public boolean complete(long maxDur) { + if(!multicore) + { + return true; + } + synchronized (futures) { if (futures.isEmpty()) { return true; 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 6b55ac000..92a07825e 100644 --- a/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java +++ b/src/main/java/com/volmit/iris/util/parallel/MultiBurst.java @@ -21,6 +21,7 @@ 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; @@ -111,6 +112,12 @@ public class MultiBurst { } } + public void sync(KList r) { + for (Runnable i : r) { + i.run(); + } + } + public BurstExecutor burst(int estimate) { return new BurstExecutor(getService(), estimate); }