Example #1
0
  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;
    }
  }
Example #6
0
  @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);
    }
  }