diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java index 7c7cbf470..f55a25e0f 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_14/BukkitGetBlocks_1_14.java @@ -211,7 +211,6 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks { } private void updateGet(BukkitGetBlocks_1_14 get, Chunk nmsChunk, ChunkSection[] sections, ChunkSection section, char[] arr, int layer) { - checkNotNull(arr); synchronized (get) { if (this.nmsChunk != nmsChunk) { this.nmsChunk = nmsChunk; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java index fe5ec23ad..d4b0582c3 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java @@ -28,10 +28,8 @@ public abstract class CharBlocks implements IBlocks { throw new IllegalStateException("Array cannot be null (update): " + blocks.getClass()); } } - synchronized (this) { - if (blocks.blocks[layer] != null) { - blocks.sections[layer] = FULL; - } + if (blocks.blocks[layer] != null) { + blocks.sections[layer] = FULL; } return arr; } @@ -52,11 +50,7 @@ public abstract class CharBlocks implements IBlocks { boolean result = true; for (int i = 0; i < 16; i++) { if (sections[i] == EMPTY && blocks[i] != null) { - synchronized (this) { - if (sections[i] == EMPTY && blocks[i] != null) { - blocks[i] = null; - } - } + blocks[i] = null; } else { result = false; } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharGetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharGetBlocks.java index a0ff14a58..9304969f3 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharGetBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharGetBlocks.java @@ -21,11 +21,9 @@ public abstract class CharGetBlocks extends CharBlocks implements IChunkGet { @Override public boolean trim(boolean aggressive) { - synchronized (this) { - for (int i = 0; i < 16; i++) { - sections[i] = EMPTY; - blocks[i] = null; - } + for (int i = 0; i < 16; i++) { + sections[i] = EMPTY; + blocks[i] = null; } return true; } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/ParallelQueueExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/ParallelQueueExtent.java index a641e099b..3ede7890b 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/ParallelQueueExtent.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/ParallelQueueExtent.java @@ -1,5 +1,6 @@ package com.boydti.fawe.beta.implementation.queue; +import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IQueueWrapper; import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock; import com.boydti.fawe.beta.Filter; @@ -10,6 +11,7 @@ import com.boydti.fawe.beta.implementation.processors.BatchProcessorHolder; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.clipboard.WorldCopyClipboard; +import com.boydti.fawe.object.extent.NullExtent; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.PassthroughExtent; @@ -56,6 +58,15 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap return (IQueueExtent) super.getExtent(); } + @Override + public boolean cancel() { + if (super.cancel()) { + processor.setProcessor(new NullExtent(this, FaweCache.MANUAL)); + return true; + } + return false; + } + private IQueueExtent getNewQueue() { return wrapQueue(handler.getQueue(this.world, this.processor)); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/QueueHandler.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/QueueHandler.java index 4c8beb6f9..43940c9d5 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/QueueHandler.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/QueueHandler.java @@ -81,6 +81,10 @@ public abstract class QueueHandler implements Trimable, Runnable { } } + public boolean isUnderutilized() { + return blockingExecutor.getActiveCount() < blockingExecutor.getMaximumPoolSize(); + } + private long getAllocate() { long now = System.currentTimeMillis(); targetTPS = 18 - Math.max(Settings.IMP.QUEUE.EXTRA_TIME_MS * 0.05, 0); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/SingleThreadQueueExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/SingleThreadQueueExtent.java index 57bc557ea..c43e49a06 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/SingleThreadQueueExtent.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/queue/SingleThreadQueueExtent.java @@ -221,17 +221,20 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen } final int size = chunks.size(); final boolean lowMem = MemUtil.isMemoryLimited(); - if (enabledQueue && (lowMem || size > Settings.IMP.QUEUE.TARGET_SIZE)) { + // If queueing is enabled AND either of the following + // - memory is low & queue size > num threads + 8 + // - queue size > target size and primary queue has less than num threads submissions + if (enabledQueue && ((lowMem && size > Settings.IMP.QUEUE.PARALLEL_THREADS + 8) || (size > Settings.IMP.QUEUE.TARGET_SIZE && Fawe.get().getQueueHandler().isUnderutilized()))) { chunk = chunks.removeFirst(); final Future future = submitUnchecked(chunk); if (future != null && !future.isDone()) { final int targetSize; if (lowMem) { - targetSize = Settings.IMP.QUEUE.PARALLEL_THREADS; + targetSize = Settings.IMP.QUEUE.PARALLEL_THREADS + 8; } else { targetSize = Settings.IMP.QUEUE.TARGET_SIZE; } - pollSubmissions(targetSize, true); + pollSubmissions(targetSize, lowMem); submissions.add(future); } } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java b/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java index 4b85d9084..c8df8d7c9 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java @@ -275,7 +275,7 @@ public class Settings extends Config { " - A value too small may break some operations (deform?)" }) - public int TARGET_SIZE = 8192; + public int TARGET_SIZE = 64; @Comment({ "Force FAWE to start placing chunks regardless of whether an edit is finished processing", " - A larger value will use slightly less CPU time", diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java index a9c85af62..dcb3a7074 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java @@ -31,6 +31,7 @@ import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockID; import com.sk89q.worldedit.world.block.BlockState; import java.io.Closeable; @@ -196,6 +197,9 @@ public abstract class FaweChangeSet implements ChangeSet, IBatchProcessor, Close for (int x = 0; x < 16; x++, index++) { int xx = bx + x; int combinedFrom = blocksGet[index]; + if (combinedFrom == 0) { + combinedFrom = BlockID.AIR; + } int combinedTo = blocksSet[index]; if (combinedTo != 0) { add(xx, yy, zz, combinedFrom, combinedTo); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index 605d6eee2..536541e45 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -325,21 +325,6 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { return player; } - public boolean cancel() { - ExtentTraverser traverser = new ExtentTraverser<>(getExtent()); - NullExtent nullExtent = new NullExtent(world, FaweCache.MANUAL); - while (traverser != null) { - Extent get = traverser.get(); - ExtentTraverser next = traverser.next(); - if (get instanceof AbstractDelegateExtent && !(get instanceof NullExtent)) { - traverser.setNext(nullExtent); - } - get.addProcessor(nullExtent); - traverser = next; - } - return super.cancel(); - } - // pkg private for TracedEditSession only, may later become public API boolean commitRequired() { return false; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java index 9772b1de4..7c17e23e6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java @@ -83,7 +83,7 @@ public class HistoryCommands { " - Import from disk: /frb #import" ) @CommandPermissions("worldedit.history.rollback") - public void faweRollback(Player player, LocalSession session, String user, @Arg(def = "0", desc = "radius") @Range(min = 0) int radius, @Arg(name = "time", desc = "String", def = "0") String time, @Switch(name = 'r', desc = "TODO") boolean restore) throws WorldEditException { + public void faweRollback(Player player, LocalSession session, @Arg(desc = "String user") String user, @Arg(def = "0", desc = "radius") @Range(min = 0) int radius, @Arg(name = "time", desc = "String", def = "0") String time, @Switch(name = 'r', desc = "TODO") boolean restore) throws WorldEditException { if (!Settings.IMP.HISTORY.USE_DATABASE) { BBC.SETTING_DISABLE.send(player, "history.use-database (Import with /frb #import )"); return; @@ -214,7 +214,7 @@ public class HistoryCommands { " - Import from disk: /frb #import" ) @CommandPermissions("worldedit.history.rollback") - public void restore(Player player, LocalSession session, String user, @Arg(def = "0", desc = "radius") @Range(min = 0) int radius, @Arg(name = "time", desc = "String", def = "0") String time) throws WorldEditException { + public void restore(Player player, LocalSession session, @Arg(desc = "String user") String user, @Arg(def = "0", desc = "radius") @Range(min = 0) int radius, @Arg(name = "time", desc = "String", def = "0") String time) throws WorldEditException { faweRollback(player, session, user, radius, time, true); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java index 3258832f7..7d6be3084 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java @@ -21,12 +21,15 @@ package com.sk89q.worldedit.extent; import static com.google.common.base.Preconditions.checkNotNull; +import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.implementation.filter.block.ExtentFilterBlock; import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.IBatchProcessor; import com.boydti.fawe.object.changeset.FaweChangeSet; import com.boydti.fawe.object.clipboard.WorldCopyClipboard; import com.boydti.fawe.object.exception.FaweException; +import com.boydti.fawe.object.extent.NullExtent; +import com.boydti.fawe.util.ExtentTraverser; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.entity.BaseEntity; @@ -453,6 +456,18 @@ public interface Extent extends InputExtent, OutputExtent { } default boolean cancel() { + ExtentTraverser traverser = new ExtentTraverser<>(this); + + NullExtent nullExtent = new NullExtent(this, FaweCache.MANUAL); + + ExtentTraverser next = traverser.next(); + if (next != null) { + Extent child = next.get(); + if (child instanceof NullExtent) return true; + traverser.setNext(nullExtent); + child.cancel(); + } + addProcessor(nullExtent); return true; }