diff --git a/CHANGELOG.md b/CHANGELOG.md index d3d927756..d5e9a50bc 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Refined Storage Changelog +### 1.4.10 +- Improved performance of network scanning (raoulvdberge) + ### 1.4.9 - Fixed bug where inventory data was lost sometimes upon opening the world (raoulvdberge) diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeGraph.java b/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeGraph.java index e30ea905e..8e5eb2c0f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeGraph.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeGraph.java @@ -2,7 +2,7 @@ package com.raoulvdberge.refinedstorage.api.network; import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode; -import java.util.List; +import java.util.Collection; /** * Represents a graph of all the nodes connected to a network. @@ -14,9 +14,9 @@ public interface INetworkNodeGraph { void rebuild(); /** - * @return a list of all connected nodes + * @return a collection of all connected nodes */ - List all(); + Collection all(); /** * Disconnects and notifies all connected nodes. diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeGraph.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeGraph.java index cddc4d878..80d41f629 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeGraph.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeGraph.java @@ -22,8 +22,8 @@ import static com.raoulvdberge.refinedstorage.proxy.CapabilityNetworkNodeProxy.N public class NetworkNodeGraph implements INetworkNodeGraph { private TileController controller; - private List nodes = new ArrayList<>(); - private Set nodePositions = new HashSet<>(); + private Set nodes = new HashSet<>(); + private Set nodeHashes = new HashSet<>(); public NetworkNodeGraph(TileController controller) { this.controller = controller; @@ -39,26 +39,7 @@ public class NetworkNodeGraph implements INetworkNodeGraph { return; } - Set newNodes = new HashSet<>(); - Set newNodePositions = new HashSet<>(); - Queue toCheck = new ArrayDeque<>(); - - INetworkNeighborhoodAware.Operator operator = (world, pos, side) -> { - TileEntity tile = world.getTileEntity(pos); - - if (tile != null && !tile.isInvalid()) { - if (tile instanceof TileController) { - removeOtherController(world, pos); - } else if (tile.hasCapability(NETWORK_NODE_PROXY_CAPABILITY, side)) { - INetworkNodeProxy otherNodeProxy = NETWORK_NODE_PROXY_CAPABILITY.cast(tile.getCapability(NETWORK_NODE_PROXY_CAPABILITY, side)); - INetworkNode otherNode = otherNodeProxy.getNode(); - - if (newNodes.add(otherNode) && newNodePositions.add(getNodeHash(otherNode))) { - toCheck.add(new NodeToCheck(otherNode, world, pos, side, tile)); - } - } - } - }; + Operator operator = new Operator(); BlockPos controllerPos = controller.getPos(); World controllerWorld = controller.getWorld(); @@ -69,35 +50,22 @@ public class NetworkNodeGraph implements INetworkNodeGraph { } NodeToCheck currentNodeToCheck; - while ((currentNodeToCheck = toCheck.poll()) != null) { + while ((currentNodeToCheck = operator.toCheck.poll()) != null) { currentNodeToCheck.walkNeighborhood(operator); } - List oldNodes = nodes; - Set oldNodePositions = nodePositions; - - nodes = new ArrayList<>(newNodes); - nodePositions = new HashSet<>(newNodePositions); - - boolean changed = false; - for (INetworkNode node : nodes) { - if (!oldNodePositions.contains(getNodeHash(node))) { - node.onConnected(controller); + if (operator.uncheckedHashesFromPrevious.contains(getNodeHash(node))) { + node.onDisconnected(controller); - changed = true; + operator.changed = true; } } - for (INetworkNode oldNode : oldNodes) { - if (!nodePositions.contains(getNodeHash(oldNode))) { - oldNode.onDisconnected(controller); + this.nodes = operator.newNodes; + this.nodeHashes = operator.newNodeHashes; - changed = true; - } - } - - if (changed) { + if (operator.changed) { controller.getDataManager().sendParameterToWatchers(TileController.NODES); } } @@ -109,7 +77,7 @@ public class NetworkNodeGraph implements INetworkNodeGraph { } @Override - public List all() { + public Collection all() { return nodes; } @@ -118,7 +86,7 @@ public class NetworkNodeGraph implements INetworkNodeGraph { List oldNodes = new ArrayList<>(nodes); nodes.clear(); - nodePositions.clear(); + nodeHashes.clear(); for (INetworkNode node : oldNodes) { if (node.getNetwork() == controller) { @@ -151,6 +119,43 @@ public class NetworkNodeGraph implements INetworkNodeGraph { } } + private class Operator implements INetworkNeighborhoodAware.Operator { + private Set newNodes = new HashSet<>(); + private Set newNodeHashes = new HashSet<>(); + private Set uncheckedHashesFromPrevious = new HashSet<>(nodeHashes); + + private boolean changed; + + private Queue toCheck = new ArrayDeque<>(); + + @Override + public void apply(World world, BlockPos pos, EnumFacing side) { + TileEntity tile = world.getTileEntity(pos); + + if (tile != null) { + if (tile instanceof TileController) { + removeOtherController(world, pos); + } else if (tile.hasCapability(NETWORK_NODE_PROXY_CAPABILITY, side)) { + INetworkNodeProxy otherNodeProxy = NETWORK_NODE_PROXY_CAPABILITY.cast(tile.getCapability(NETWORK_NODE_PROXY_CAPABILITY, side)); + INetworkNode otherNode = otherNodeProxy.getNode(); + int otherNodeHash = getNodeHash(otherNode); + + if (newNodes.add(otherNode) && newNodeHashes.add(otherNodeHash)) { + if (!nodeHashes.contains(otherNodeHash)) { + otherNode.onConnected(controller); + + changed = true; + } + + uncheckedHashesFromPrevious.remove(otherNodeHash); + + toCheck.add(new NodeToCheck(otherNode, world, pos, side, tile)); + } + } + } + } + } + private class NodeToCheck implements INetworkNeighborhoodAware { private final INetworkNode node; private final World world;