From 8e8a87fce666b19b33981479e67b47121992b5ea Mon Sep 17 00:00:00 2001 From: TheBusyBiscuit Date: Mon, 17 Aug 2020 17:31:15 +0200 Subject: [PATCH] Fixed ChestTerminal timings showing up as cargo nodes --- CHANGELOG.md | 4 ++ .../core/networks/cargo/CargoNet.java | 2 +- .../core/networks/cargo/CargoNetworkTask.java | 7 ++- .../core/networks/cargo/CargoUtils.java | 32 ++++++++--- .../networks/cargo/ChestTerminalNetwork.java | 54 +++++++++++-------- .../services/profiler/SlimefunProfiler.java | 13 +++-- 6 files changed, 78 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 187e0a41c..b5821b674 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,8 @@ * Performance improvements for idling Enhanced Furnaces when using Paper * Performance improvements for Rainbow Blocks * Crafting a Rag now yields two items +* Small performance improvements for Slimefun guides +* Small performance improvements for Cargo networks #### Fixes * Fixed Programmable Androids rotating in the wrong direction @@ -64,6 +66,8 @@ * Fixed Miner Talisman sending messages when drops were not even doubled * Fixed #2077 * Fixed #2207 +* Fixed ChestTerminal timings showing up as cargo nodes +* Fixed timings reports never arriving sometimes ## Release Candidate 15 (01 Aug 2020) diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java index f8df07d58..681fffaaa 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java @@ -175,7 +175,7 @@ public class CargoNet extends ChestTerminalNetwork { display(); } - SlimefunPlugin.getProfiler().scheduleEntries(1 + inputNodes.size()); + SlimefunPlugin.getProfiler().scheduleEntries((terminals.isEmpty() ? 1 : 2) + inputs.size()); CargoNetworkTask runnable = new CargoNetworkTask(this, inputs, outputs, chestTerminalInputs, chestTerminalOutputs); Slimefun.runSync(runnable); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNetworkTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNetworkTask.java index eec1652df..11b87f47e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNetworkTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNetworkTask.java @@ -16,6 +16,7 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; @@ -63,6 +64,7 @@ class CargoNetworkTask implements Runnable { // All operations happen here: Everything gets iterated from the Input Nodes. // (Apart from ChestTerminal Buses) + SlimefunItem inputNode = SlimefunItems.CARGO_INPUT_NODE.getItem(); for (Map.Entry entry : inputs.entrySet()) { long nodeTimestamp = System.nanoTime(); Location input = entry.getKey(); @@ -71,12 +73,13 @@ class CargoNetworkTask implements Runnable { attachedBlock.ifPresent(block -> routeItems(input, block, entry.getValue(), outputs)); // This will prevent this timings from showing up for the Cargo Manager - timestamp += SlimefunPlugin.getProfiler().closeEntry(entry.getKey(), SlimefunItems.CARGO_INPUT_NODE.getItem(), nodeTimestamp); + timestamp += SlimefunPlugin.getProfiler().closeEntry(entry.getKey(), inputNode, nodeTimestamp); } // Chest Terminal Code if (SlimefunPlugin.getThirdPartySupportService().isChestTerminalInstalled()) { - network.updateTerminals(chestTerminalInputs); + // This will deduct any CT timings and attribute them towards the actual terminal + timestamp += network.updateTerminals(chestTerminalInputs); } // Submit a timings report diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java index b13b43d67..561cb30bc 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java @@ -409,18 +409,36 @@ final class CargoUtils { } private static boolean matchesFilterList(ItemStack item, BlockMenu menu, boolean respectLore, boolean defaultValue) { - ItemStackWrapper wrapper = null; + // Little performance optimization: + // First check if there is more than one item to compare, if so + // then we know we should create an ItemStackWrapper, otherwise it would + // be of no benefit to us and just be redundant + int itemsToCompare = 0; for (int slot : FILTER_SLOTS) { ItemStack stack = menu.getItemInSlot(slot); - if (stack != null) { - if (wrapper == null) { - // Only create this as needed to save performance - wrapper = new ItemStackWrapper(item); - } + if (stack != null && stack.getType() != Material.AIR) { + itemsToCompare++; - if (SlimefunUtils.isItemSimilar(stack, wrapper, respectLore, false)) { + if (itemsToCompare > 1) { + break; + } + } + } + + // Check if there are event non-air items + if (itemsToCompare > 0) { + // Only create the Wrapper if its worth it + if (itemsToCompare > 1) { + // Create an itemStackWrapper to save performance + item = new ItemStackWrapper(item); + } + + for (int slot : FILTER_SLOTS) { + ItemStack stack = menu.getItemInSlot(slot); + + if (SlimefunUtils.isItemSimilar(stack, item, respectLore, false)) { return !defaultValue; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ChestTerminalNetwork.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ChestTerminalNetwork.java index d7d1a0cfe..1a9fe1077 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ChestTerminalNetwork.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ChestTerminalNetwork.java @@ -274,37 +274,49 @@ abstract class ChestTerminalNetwork extends Network { * * @param providers * A {@link Set} of providers to this {@link ChestTerminalNetwork} + * + * @return The time it took to compute this operation */ - protected void updateTerminals(Set providers) { + protected long updateTerminals(Set providers) { if (terminals.isEmpty()) { // Performance improvement - We don't need to compute items for // Cargo networks without any Chest Terminals - return; + return 0; } - // Timings will be slightly inaccurate here but most often people are gonna - // use no more than one terminal anyway, so this might be fine - long timestamp = SlimefunPlugin.getProfiler().newEntry(); + // Timings will be slightly inaccurate here but most often people are not + // gonna use no more than one terminal anyway, so this might be fine + long timestamp = System.nanoTime(); + Location firstTerminal = null; SlimefunItem item = SlimefunItem.getByID("CHEST_TERMINAL"); List items = findAvailableItems(providers); - for (Location l : terminals) { - BlockMenu terminal = BlockStorage.getInventory(l); - int page = Integer.parseInt(BlockStorage.getLocationInfo(l, "page")); + try { + for (Location l : terminals) { + BlockMenu terminal = BlockStorage.getInventory(l); + int page = Integer.parseInt(BlockStorage.getLocationInfo(l, "page")); - if (!items.isEmpty() && items.size() < (page - 1) * TERMINAL_SLOTS.length + 1) { - page = 1; - BlockStorage.addBlockInfo(l, "page", String.valueOf(1)); + if (!items.isEmpty() && items.size() < (page - 1) * TERMINAL_SLOTS.length + 1) { + page = 1; + BlockStorage.addBlockInfo(l, "page", String.valueOf(1)); + } + + for (int i = 0; i < TERMINAL_SLOTS.length; i++) { + int slot = TERMINAL_SLOTS[i]; + int index = i + (TERMINAL_SLOTS.length * (page - 1)); + updateTerminal(l, terminal, slot, index, items); + } + + if (firstTerminal == null) { + firstTerminal = l; + } } - - for (int i = 0; i < TERMINAL_SLOTS.length; i++) { - int slot = TERMINAL_SLOTS[i]; - int index = i + (TERMINAL_SLOTS.length * (page - 1)); - updateTerminal(l, terminal, slot, index, items); - } - - SlimefunPlugin.getProfiler().closeEntry(l, item, timestamp); } + catch (Exception | LinkageError x) { + item.error("An Exception was caused while trying to tick Chest terminals", x); + } + + return SlimefunPlugin.getProfiler().closeEntry(firstTerminal, item, timestamp); } private void updateTerminal(Location l, BlockMenu terminal, int slot, int index, List items) { @@ -316,7 +328,7 @@ abstract class ChestTerminalNetwork extends Network { ItemMeta im = stack.getItemMeta(); List lore = new ArrayList<>(); lore.add(""); - lore.add(ChatColors.color("&7Stored Items: &r" + DoubleHandler.getFancyDouble(item.getInt()))); + lore.add(ChatColors.color("&7Stored Items: &f" + DoubleHandler.getFancyDouble(item.getInt()))); if (stack.getMaxStackSize() > 1) { int amount = item.getInt() > stack.getMaxStackSize() ? stack.getMaxStackSize() : item.getInt(); @@ -437,7 +449,7 @@ abstract class ChestTerminalNetwork extends Network { boolean add = true; for (ItemStackAndInteger item : items) { - if (SlimefunUtils.isItemSimilar(stack, item.getItemStackWrapper(), true)) { + if (SlimefunUtils.isItemSimilar(stack, item.getItemStackWrapper(), true, false)) { add = false; item.add(stack.getAmount()); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java index fad49ad33..98b012e59 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/profiler/SlimefunProfiler.java @@ -44,7 +44,7 @@ public class SlimefunProfiler { // two ticks (sync and async blocks), so we use 100ms as a reference here private static final int MAX_TICK_DURATION = 100; - private final ExecutorService executor = Executors.newFixedThreadPool(4); + private final ExecutorService executor = Executors.newFixedThreadPool(5); private final AtomicBoolean running = new AtomicBoolean(false); private final AtomicInteger queued = new AtomicInteger(0); @@ -118,7 +118,8 @@ public class SlimefunProfiler { executor.execute(() -> { ProfiledBlock block = new ProfiledBlock(l, item); - timings.putIfAbsent(block, elapsedTime); + // Merge (if we have multiple samples for whatever reason) + timings.merge(block, elapsedTime, Long::sum); queued.decrementAndGet(); }); @@ -143,7 +144,7 @@ public class SlimefunProfiler { private void finishReport() { // We will only wait for a maximum of this many 1ms sleeps - int iterations = 1000; + int iterations = 4000; // Wait for all timing results to come in while (!running.get() && queued.get() > 0) { @@ -153,6 +154,12 @@ public class SlimefunProfiler { // If we waited for too long, then we should just abort if (iterations <= 0) { + Iterator iterator = requests.iterator(); + + while (iterator.hasNext()) { + iterator.next().sendMessage("Your timings report has timed out, we were still waiting for " + queued.get() + " samples to be collected :/"); + iterator.remove(); + } return; } }