diff --git a/core/src/main/java/com/boydti/fawe/FaweCache.java b/core/src/main/java/com/boydti/fawe/FaweCache.java index 588ec85a..56b84f68 100644 --- a/core/src/main/java/com/boydti/fawe/FaweCache.java +++ b/core/src/main/java/com/boydti/fawe/FaweCache.java @@ -349,53 +349,142 @@ public class FaweCache { switch (id) { case 0: case 6: + case 8: + case 9: + case 10: + case 11: + case 18: + case 20: + case 26: case 27: case 28: + case 29: + case 30: case 31: case 32: + case 33: + case 34: + case 36: case 37: case 38: case 39: case 40: + case 44: + case 46: case 50: case 51: + case 53: + case 54: case 55: case 59: + case 60: + case 63: + case 64: case 65: case 66: + case 67: + case 68: case 69: + case 70: + case 71: + case 72: case 75: case 76: case 77: case 78: + case 79: + case 81: case 83: + case 85: + case 89: case 90: + case 92: case 93: case 94: + case 95: + case 96: + case 101: + case 102: case 104: case 105: case 106: + case 107: + case 108: + case 109: case 111: + case 113: + case 114: case 115: + case 116: + case 117: + case 118: case 119: + case 120: + case 122: + case 126: case 127: + case 128: + case 130: case 131: case 132: + case 134: + case 135: + case 136: + case 138: + case 139: case 140: case 141: case 142: case 143: case 144: + case 145: + case 146: + case 147: + case 148: case 149: case 150: + case 151: + case 152: + case 154: + case 156: case 157: + case 160: + case 161: + case 163: + case 164: + case 167: + case 169: case 171: case 175: + case 176: + case 177: + case 178: + case 180: + case 182: + case 183: + case 184: + case 185: + case 186: + case 187: + case 188: + case 189: + case 190: + case 191: + case 192: + case 193: + case 194: + case 195: + case 196: + case 197: case 198: case 199: case 200: + case 203: + case 205: case 207: + case 208: case 209: + case 212: case 217: return true; default: return false; diff --git a/core/src/main/java/com/boydti/fawe/command/Reload.java b/core/src/main/java/com/boydti/fawe/command/Reload.java index 50d32ea0..50088867 100644 --- a/core/src/main/java/com/boydti/fawe/command/Reload.java +++ b/core/src/main/java/com/boydti/fawe/command/Reload.java @@ -10,6 +10,7 @@ import com.boydti.fawe.util.MainUtil; import java.io.File; import java.io.IOException; import java.util.Date; +import java.util.Map; public class Reload extends FaweCommand { @@ -20,7 +21,7 @@ public class Reload extends FaweCommand { @Override public boolean execute(final FawePlayer player, final String... args) { if (args.length != 1) { - BBC.COMMAND_SYNTAX.send(player, "/fawe [reload|version"); + BBC.COMMAND_SYNTAX.send(player, "/fawe [reload|version|debugpaste|threads]"); return false; } switch (args[0].toLowerCase()) { @@ -35,6 +36,19 @@ public class Reload extends FaweCommand { MainUtil.sendMessage(player, "Version Build: #" + version.build); return true; } + case "threads": { + Map stacks = Fawe.get().getMainThread().getAllStackTraces(); + for (Map.Entry entry : stacks.entrySet()) { + Thread thread = entry.getKey(); + Fawe.debug("--------------------------------------------------------------------------------------------"); + Fawe.debug("Thread: " + thread.getName() + " | Id: " + thread.getId() + " | Alive: " + thread.isAlive()); + for (StackTraceElement elem : entry.getValue()) { + Fawe.debug(elem); + } + } + player.sendMessage("&cSee console."); + return true; + } case "debugpaste": case "paste": { try { @@ -84,7 +98,7 @@ public class Reload extends FaweCommand { return true; } default: - BBC.COMMAND_SYNTAX.send(player, "/fawe [reload|version]"); + BBC.COMMAND_SYNTAX.send(player, "/fawe [reload|version|debugpaste|threads]"); return false; } } diff --git a/core/src/main/java/com/boydti/fawe/example/MappedFaweQueue.java b/core/src/main/java/com/boydti/fawe/example/MappedFaweQueue.java index f2704e59..d7683456 100644 --- a/core/src/main/java/com/boydti/fawe/example/MappedFaweQueue.java +++ b/core/src/main/java/com/boydti/fawe/example/MappedFaweQueue.java @@ -21,6 +21,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.UUID; import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.TimeUnit; public abstract class MappedFaweQueue extends FaweQueue { @@ -52,27 +54,20 @@ public abstract class MappedFaweQueue extends FaweQueue { @Override public void optimize() { - final ArrayList threads = new ArrayList(); + final ForkJoinPool pool = TaskManager.IMP.getPublicForkJoinPool(); + final ArrayList threads = new ArrayList(map.size()); map.forEachChunk(new RunnableVal() { @Override public void run(final FaweChunk chunk) { - Thread thread = new Thread(new Runnable() { + pool.submit(new Runnable() { @Override public void run() { chunk.optimize(); } }); - threads.add(thread); - thread.start(); } }); - for (Thread thread : threads) { - try { - thread.join(); - } catch (InterruptedException e) { - MainUtil.handleError(e); - } - } + pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS); } @Override diff --git a/core/src/main/java/com/boydti/fawe/example/NMSRelighter.java b/core/src/main/java/com/boydti/fawe/example/NMSRelighter.java index 84cc5943..28b98616 100644 --- a/core/src/main/java/com/boydti/fawe/example/NMSRelighter.java +++ b/core/src/main/java/com/boydti/fawe/example/NMSRelighter.java @@ -136,7 +136,7 @@ public class NMSRelighter { } private boolean isTransparent(int x, int y, int z) { - return FaweCache.isTransparent(FaweCache.getId(queue.getCombinedId4Data(x, y, z))); + return queue.getOpacity(x, y, z) < 15; } public void lightBlock(int x, int y, int z, int brightness) { diff --git a/core/src/main/java/com/boydti/fawe/util/SetQueue.java b/core/src/main/java/com/boydti/fawe/util/SetQueue.java index 89c8d0b7..e3d94668 100644 --- a/core/src/main/java/com/boydti/fawe/util/SetQueue.java +++ b/core/src/main/java/com/boydti/fawe/util/SetQueue.java @@ -9,6 +9,8 @@ import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.TimeUnit; public class SetQueue { @@ -53,6 +55,8 @@ public class SetQueue { } }; + private ForkJoinPool pool = new ForkJoinPool(); + public SetQueue() { tasks = new ConcurrentLinkedDeque<>(); activeQueues = new ConcurrentLinkedDeque(); @@ -100,20 +104,10 @@ public class SetQueue { if (Settings.QUEUE.PARALLEL_THREADS <= 1) { SET_TASK.run(); } else { - Thread[] threads = new Thread[Settings.QUEUE.PARALLEL_THREADS]; for (int i = 0; i < Settings.QUEUE.PARALLEL_THREADS; i++) { - threads[i] = (new Thread(SET_TASK)); - } - for (Thread thread : threads) { - thread.start(); - } - for (Thread thread : threads) { - try { - thread.join(); - } catch (InterruptedException e) { - MainUtil.handleError(e); - } + pool.submit(SET_TASK); } + pool.awaitQuiescence(Settings.QUEUE.DISCARD_AFTER_MS, TimeUnit.MILLISECONDS); } } catch (Throwable e) { MainUtil.handleError(e); @@ -198,20 +192,10 @@ public class SetQueue { if (!parallel) { SET_TASK.run(); } else { - Thread[] threads = new Thread[Settings.QUEUE.PARALLEL_THREADS]; for (int i = 0; i < Settings.QUEUE.PARALLEL_THREADS; i++) { - threads[i] = (new Thread(SET_TASK)); - } - for (Thread thread : threads) { - thread.start(); - } - for (Thread thread : threads) { - try { - thread.join(); - } catch (InterruptedException e) { - MainUtil.handleError(e); - } + pool.submit(SET_TASK); } + pool.awaitQuiescence(Settings.QUEUE.DISCARD_AFTER_MS, TimeUnit.MILLISECONDS); } } catch (Throwable e) { MainUtil.handleError(e); diff --git a/core/src/main/java/com/boydti/fawe/util/TaskManager.java b/core/src/main/java/com/boydti/fawe/util/TaskManager.java index f98b1033..20926901 100644 --- a/core/src/main/java/com/boydti/fawe/util/TaskManager.java +++ b/core/src/main/java/com/boydti/fawe/util/TaskManager.java @@ -6,6 +6,8 @@ import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.RunnableVal; import java.util.Collection; import java.util.Iterator; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import javax.annotation.Nullable; @@ -13,6 +15,8 @@ public abstract class TaskManager { public static TaskManager IMP; + private ForkJoinPool pool = new ForkJoinPool(); + /** * Run a repeating task on the main thread * @param r @@ -41,11 +45,33 @@ public abstract class TaskManager { */ public abstract void task(final Runnable r); + /** + * Get the public ForkJoinPool
+ * - ONLY SUBMIT SHORT LIVED TASKS
+ * - DO NOT USE SLEEP/WAIT/LOCKS IN ANY SUBMITTED TASKS
+ * @return + */ + public ForkJoinPool getPublicForkJoinPool() { + return pool; + } + + /** + * Run a buch of tasks in parallel using the shared thread pool + * @param runnables + */ + public void parallel(Collection runnables) { + for (Runnable run : runnables) { + pool.submit(run); + } + pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS); + } + /** * Run a bunch of tasks in parallel * @param runnables The tasks to run * @param numThreads Number of threads (null = config.yml parallel threads) */ + @Deprecated public void parallel(Collection runnables, @Nullable Integer numThreads) { if (runnables == null) { return; diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index 76e37984..9df5f5aa 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -1109,9 +1109,7 @@ public class EditSession implements Extent { public void flushQueue() { Operations.completeBlindly(commit()); // Enqueue it - if (queue != null && queue.size() > 0) { - queue.enqueue(); - } else { + if (queue == null || queue.size() == 0) { queue.dequeue(); return; } diff --git a/core/src/main/java/com/sk89q/worldedit/command/composition/SelectionCommand.java b/core/src/main/java/com/sk89q/worldedit/command/composition/SelectionCommand.java index e2e739e0..00034677 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/composition/SelectionCommand.java +++ b/core/src/main/java/com/sk89q/worldedit/command/composition/SelectionCommand.java @@ -23,11 +23,10 @@ import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.FaweQueue; -import com.boydti.fawe.object.NullChangeSet; import com.boydti.fawe.object.RegionWrapper; import com.boydti.fawe.object.RunnableVal; +import com.boydti.fawe.object.extent.FaweRegionExtent; import com.boydti.fawe.util.MainUtil; -import com.boydti.fawe.util.WEManager; import com.google.common.base.Joiner; import com.google.common.collect.Lists; import com.sk89q.minecraft.util.commands.CommandException; @@ -99,9 +98,9 @@ public class SelectionCommand extends SimpleCommand { RegionFunction function = ((RegionVisitor) operation).function; RegionWrapper current = new RegionWrapper(cuboid.getMinimumPoint(), cuboid.getMaximumPoint()); FawePlayer fp = FawePlayer.wrap(player); - RegionWrapper[] mask = WEManager.IMP.getMask(fp); + FaweRegionExtent regionExtent = editSession.getRegionExtent(); - if (function instanceof BlockReplace && mask.length == 1 && mask[0].equals(current)) { + if (function instanceof BlockReplace && regionExtent == null) { try { BlockReplace replace = ((BlockReplace) function); Field field = replace.getClass().getDeclaredField("pattern"); @@ -149,8 +148,10 @@ public class SelectionCommand extends SimpleCommand { } }); queue.enqueue(); - editSession.setChangeSet(new NullChangeSet(null)); + long start = System.currentTimeMillis(); BBC.OPERATION.send(actor, BBC.VISITOR_BLOCK.format(cuboid.getArea())); + queue.flush(); + BBC.ACTION_COMPLETE.send(actor, start); return null; } } catch (Throwable e) {