private boolean isInDistanceInternal( int distance, NetworkNode from, NetworkNode to, TwoNetworkNodes cachePairKey) { if (from.equals(to)) return true; if (distance == 0) return false; if (SimpleNetwork.areNodesConnecting(from, to)) return true; // Breadth-first search of the network Set<NetworkNode> visitedNodes = Sets.newHashSet(); visitedNodes.add(from); Set<NetworkNode> networkingNodesToTest = Sets.newHashSet(); listConnectedNotVisitedNetworkingNodes(visitedNodes, from, networkingNodesToTest); int distanceSearched = 1; while (distanceSearched < distance) { distanceSearched++; for (NetworkNode nodeToTest : networkingNodesToTest) { if (SimpleNetwork.areNodesConnecting(nodeToTest, to)) { distanceCache.put(cachePairKey, distanceSearched); return true; } visitedNodes.add(nodeToTest); } Set<NetworkNode> nextNetworkingNodesToTest = Sets.newHashSet(); for (NetworkNode nodeToTest : networkingNodesToTest) listConnectedNotVisitedNetworkingNodes(visitedNodes, nodeToTest, nextNetworkingNodesToTest); networkingNodesToTest = nextNetworkingNodesToTest; } return false; }
public void removeLeafBlock(T networkNode) { validateNotMutating(); mutating = true; try { if (!leafNodes.remove(networkNode.location, networkNode)) { throw new IllegalArgumentException("Leaf node not found in the BlockNetwork"); } final Iterator<SimpleNetwork<T>> networkIterator = networks.iterator(); while (networkIterator.hasNext()) { final SimpleNetwork<T> network = networkIterator.next(); if (network.hasLeafNode(networkNode)) { boolean degenerate = network.removeLeafNode(networkNode); if (!degenerate) { notifyLeafNodesRemoved(network, Collections.singleton(networkNode)); } else { T onlyLeafNode = network.getLeafNodes().iterator().next(); notifyLeafNodesRemoved(network, Sets.newHashSet(networkNode, onlyLeafNode)); networkIterator.remove(); notifyNetworkRemoved(network); } } } } finally { mutating = false; } }
public void addLeafBlock(T networkNode) { validateNotMutating(); mutating = true; try { validateNoLeafOverlap(networkNode); for (SimpleNetwork<T> network : networks) { if (network.canAddLeafNode(networkNode)) { network.addLeafNode(networkNode); notifyLeafNodesAdded(network, Collections.singleton(networkNode)); } } // Check for new degenerated networks for (T leafNode : leafNodes.values()) { if (SimpleNetwork.areNodesConnecting(networkNode, leafNode)) { SimpleNetwork<T> degenerateNetwork = SimpleNetwork.createDegenerateNetwork(networkNode, leafNode); networks.add(degenerateNetwork); notifyNetworkAdded(degenerateNetwork); notifyLeafNodesAdded(degenerateNetwork, Sets.newHashSet(networkNode, leafNode)); } } leafNodes.put(networkNode.location, networkNode); } finally { mutating = false; } }
private SimpleNetwork<T> findNetworkWithNetworkingBlock(T networkNode) { for (SimpleNetwork<T> network : networks) { if (network.hasNetworkingNode(networkNode)) { return network; } } return null; }
public void removeNetworkingBlocks(Collection<T> networkNodes) { if (networkNodes.size() == 0) { return; } // This performance improvement is needed until the split detection (above) is improved, after // that it can be // removed validateNotMutating(); mutating = true; try { Set<SimpleNetwork<T>> affectedNetworks = Sets.newHashSet(); for (T networkNode : networkNodes) { final SimpleNetwork<T> networkWithBlock = findNetworkWithNetworkingBlock(networkNode); if (networkWithBlock == null) { throw new IllegalStateException( "Trying to remove a networking block that doesn't belong to any network"); } affectedNetworks.add(networkWithBlock); networkingNodes.remove(networkNode.location, networkNode); } List<Set<T>> listOfNodesFromModifiedNetworks = Lists.newLinkedList(); for (SimpleNetwork<T> networkWithBlock : affectedNetworks) { Set<T> leafNodesToNotify = Sets.newHashSet(networkWithBlock.getLeafNodes()); Set<T> networkingNodesToNotify = Sets.newHashSet(networkWithBlock.getNetworkingNodes()); networkWithBlock.removeAllLeafNodes(); notifyLeafNodesAdded(networkWithBlock, leafNodesToNotify); networkWithBlock.removeAllNetworkingNodes(); notifyNetworkingNodesRemoved( networkWithBlock, Collections.unmodifiableSet(networkingNodesToNotify)); networks.remove(networkWithBlock); notifyNetworkRemoved(networkWithBlock); } for (Set<T> networkingNodesInModifiedNetwork : listOfNodesFromModifiedNetworks) { for (T networkingNode : networkingNodesInModifiedNetwork) { if (!networkNodes.contains(networkingNode)) { addNetworkingBlockInternal(networkingNode); } } } } finally { mutating = false; } }
@Override public int getDistance(NetworkNode from, NetworkNode to) { TwoNetworkNodes nodePair = new TwoNetworkNodes(from, to); final Integer cachedDistance = distanceCache.get(nodePair); if (cachedDistance != null) return cachedDistance; if ((!hasNetworkingNode(from) && !hasLeafNode(from)) || (!hasNetworkingNode(to) && !hasLeafNode(to))) throw new IllegalArgumentException("Cannot test nodes not in network"); if (from.equals(to)) return 0; if (SimpleNetwork.areNodesConnecting(from, to)) return 1; // Breadth-first search of the network Set<NetworkNode> visitedNodes = Sets.newHashSet(); visitedNodes.add(from); Set<NetworkNode> networkingNodesToTest = Sets.newHashSet(); listConnectedNotVisitedNetworkingNodes(visitedNodes, from, networkingNodesToTest); int distanceSearched = 1; while (networkingNodesToTest.size() > 0) { distanceSearched++; for (NetworkNode nodeToTest : networkingNodesToTest) { if (SimpleNetwork.areNodesConnecting(nodeToTest, to)) { distanceCache.put(new TwoNetworkNodes(from, to), distanceSearched); return distanceSearched; } visitedNodes.add(nodeToTest); } Set<NetworkNode> nextNetworkingNodesToTest = Sets.newHashSet(); for (NetworkNode nodeToTest : networkingNodesToTest) listConnectedNotVisitedNetworkingNodes(visitedNodes, nodeToTest, nextNetworkingNodesToTest); networkingNodesToTest = nextNetworkingNodesToTest; } return -1; }
public void removeNetworkingBlock(T networkNode) { validateNotMutating(); mutating = true; try { SimpleNetwork<T> networkWithBlock = findNetworkWithNetworkingBlock(networkNode); if (networkWithBlock == null) { throw new IllegalStateException( "Trying to remove a networking block that doesn't belong to any network"); } networkingNodes.remove(networkNode.location, networkNode); // Naive implementation, just remove everything and start over // TODO: Improve to actually detects the branches of splits and build separate network for // each disjunctioned // TODO: network Set<T> networkingNodesToNotify = Sets.newHashSet(networkWithBlock.getNetworkingNodes()); Set<T> leafNodesToNotify = Sets.newHashSet(networkWithBlock.getLeafNodes()); networkWithBlock.removeAllLeafNodes(); notifyLeafNodesRemoved(networkWithBlock, leafNodesToNotify); networkWithBlock.removeAllNetworkingNodes(); notifyNetworkingNodesRemoved( networkWithBlock, Collections.unmodifiableSet(networkingNodesToNotify)); networks.remove(networkWithBlock); notifyNetworkRemoved(networkWithBlock); for (T networkingNode : networkingNodesToNotify) { if (!networkingNode.equals(networkNode)) { addNetworkingBlockInternal(networkingNode); } } } finally { mutating = false; } }
private void addNetworkingBlockInternal(T networkNode) { SimpleNetwork<T> addToNetwork = null; Set<T> networkingNodesToAdd = Sets.newHashSet(); networkingNodesToAdd.add(networkNode); Set<T> newLeafNodes = Sets.newHashSet(); // Try adding to existing networks final Iterator<SimpleNetwork<T>> networkIterator = networks.iterator(); while (networkIterator.hasNext()) { final SimpleNetwork<T> network = networkIterator.next(); if (network.canAddNetworkingNode(networkNode)) { if (addToNetwork == null) { addToNetwork = network; } else { Set<T> networkingNodesToNotify = Sets.newHashSet(network.getNetworkingNodes()); Set<T> leafNodesToNotify = Sets.newHashSet(network.getLeafNodes()); networkingNodesToAdd.addAll(networkingNodesToNotify); newLeafNodes.addAll(leafNodesToNotify); network.removeAllLeafNodes(); notifyLeafNodesRemoved(network, leafNodesToNotify); network.removeAllNetworkingNodes(); notifyNetworkingNodesRemoved(network, networkingNodesToNotify); networkIterator.remove(); notifyNetworkRemoved(network); } } } // If it's not in any networks, create a new one if (addToNetwork == null) { SimpleNetwork<T> newNetwork = new SimpleNetwork<>(); networks.add(newNetwork); notifyNetworkAdded(newNetwork); addToNetwork = newNetwork; } for (T networkingNode : networkingNodesToAdd) { addToNetwork.addNetworkingNode(networkingNode); } notifyNetworkingNodesAdded(addToNetwork, networkingNodesToAdd); for (T leafNode : newLeafNodes) { addToNetwork.addLeafNode(leafNode); } // Find all leaf nodes that it joins to its network for (T leafNode : leafNodes.values()) { if (addToNetwork.canAddLeafNode(leafNode)) { addToNetwork.addLeafNode(leafNode); newLeafNodes.add(leafNode); } } if (newLeafNodes.size() > 0) { notifyLeafNodesAdded(addToNetwork, newLeafNodes); } }