Java Code Examples for java.util.ArrayDeque#removeFirst()

The following examples show how to use java.util.ArrayDeque#removeFirst() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: TestBase.java    From dfalex with Apache License 2.0 6 votes vote down vote up
int _countStates(DfaState<?>... starts)
{
    ArrayDeque<DfaState<?>> togo = new ArrayDeque<>();
    HashSet<DfaState<?>> checkSet = new HashSet<>();
    for (DfaState<?> start : starts)
    {
        if (checkSet.add(start))
        {
            togo.add(start);
        }
    }
    while(!togo.isEmpty())
    {
        DfaState<?> scanst = togo.removeFirst();
        scanst.enumerateTransitions((c1,c2,newstate)->{
            if (checkSet.add(newstate))
            {
                togo.add(newstate);
            }
        });
    }
    return checkSet.size();
}
 
Example 2
Source File: ArrangementUtilities.java    From constellation with Apache License 2.0 6 votes vote down vote up
/**
 * Given a vertex, find all of the vertices in its component.
 *
 * @param rg The graph containing the vertex.
 * @param seedVxId The vertex to start from.
 *
 * @return A Set&lt;Integer&gt; containing all of the vertices in the same
 * component as rootVxId.
 */
public static Set<Integer> getComponentContainingVertex(final GraphReadMethods rg, final int seedVxId) {
    final Set<Integer> component = new HashSet<>();

    final ArrayDeque<Integer> neighbours = new ArrayDeque<>();
    neighbours.add(seedVxId);
    component.add(seedVxId);
    while (!neighbours.isEmpty()) {
        final Integer vxId = neighbours.removeFirst();
        final int nNeighbours = rg.getVertexNeighbourCount(vxId);
        for (int nbPosition = 0; nbPosition < nNeighbours; nbPosition++) {
            final int nbId = rg.getVertexNeighbour(vxId, nbPosition);

            if (!component.contains(nbId)) {
                neighbours.add(nbId);
                component.add(nbId);
            }
        }
    }

    return component;
}
 
Example 3
Source File: ArrangementUtilities.java    From constellation with Apache License 2.0 6 votes vote down vote up
/**
     * Given a vertex, find all of the vertices in its component.
     *
     * @param graph The graph containing the vertex.
     * @param seedVxId The vertex to start from.
     * @param verticesToArrange a BitSet specifying which vertices to arrange.
     *
     * @return A Set&lt;Integer%gt; containing all of the vertices in the same
     * component as rootVxId.
     */
    @Deprecated
    public static Set<Integer> getComponentContainingVertex(final GraphReadMethods graph, final int seedVxId, final BitSet verticesToArrange) {
        final Set<Integer> component = new HashSet<>();

        final ArrayDeque<Integer> neighbours = new ArrayDeque<>();
        neighbours.add(seedVxId);
        component.add(seedVxId);
        while (!neighbours.isEmpty()) {
            final Integer vxId = neighbours.removeFirst();
//            component.add(vxId);
//            Debug.debug("@added to component: %d (%d)\n", vxId, component.size());
            final int nNeighbours = graph.getVertexNeighbourCount(vxId);
            for (int nbPosition = 0; nbPosition < nNeighbours; nbPosition++) {
                final int nbId = graph.getVertexNeighbour(vxId, nbPosition);

                if (verticesToArrange.get(nbId) && !component.contains(nbId)) {
                    neighbours.add(nbId);
                    component.add(nbId);
                }
            }
        }

        return component;
    }
 
Example 4
Source File: StringUtils.java    From pnc with Apache License 2.0 6 votes vote down vote up
public static void readStream(
        InputStream inputStream,
        Charset charset,
        ArrayDeque<String> lines,
        int maxMessageSize,
        Consumer<String> droppedLinesConsumer) throws IOException {
    InputStreamReader inputStreamReader = new InputStreamReader(inputStream, charset);
    BufferedReader reader = new BufferedReader(inputStreamReader);

    int messageSize = 0;
    while (true) {
        String line = reader.readLine();
        if (line == null) {
            break;
        }
        if (maxMessageSize > -1) {
            messageSize += line.length();
            while (messageSize > maxMessageSize) {
                String removedLine = lines.removeFirst();
                messageSize -= removedLine.length();
                droppedLinesConsumer.accept(removedLine);
            }
        }
        lines.add(line);
    }
}
 
Example 5
Source File: Solution5.java    From LeetCode-Solution-in-Good-Style with Apache License 2.0 6 votes vote down vote up
public int[] maxSlidingWindow(int[] nums, int k) {
    int len = nums.length;
    if (len == 0) {
        return new int[0];
    }
    int[] res = new int[len - k + 1];
    ArrayDeque<Integer> queue = new ArrayDeque<>(len);
    for (int i = 0; i < len; i++) {
        // 左边界滑出
        if (i >= k && queue.getFirst() == i - k) {
            queue.removeFirst();
        }

        // 在 nums[i] 加入之前考虑把不可能的值弹出
        while (!queue.isEmpty() && nums[queue.getLast()] <= nums[i]) {
            queue.removeLast();
        }

        queue.add(i);
        // 记录结果
        if (i >= k - 1) {
            res[i - k + 1] = nums[queue.getFirst()];
        }
    }
    return res;
}
 
Example 6
Source File: ExecutionGraphDeploymentTest.java    From flink with Apache License 2.0 5 votes vote down vote up
private Tuple2<ExecutionGraph, Map<ExecutionAttemptID, Execution>> setupExecution(JobVertex v1, int dop1, JobVertex v2, int dop2) throws Exception {
	v1.setParallelism(dop1);
	v2.setParallelism(dop2);

	v1.setInvokableClass(BatchTask.class);
	v2.setInvokableClass(BatchTask.class);

	final ArrayDeque<CompletableFuture<LogicalSlot>> slotFutures = new ArrayDeque<>();
	for (int i = 0; i < dop1 + dop2; i++) {
		slotFutures.addLast(CompletableFuture.completedFuture(new TestingLogicalSlotBuilder().createTestingLogicalSlot()));
	}

	final SlotProvider slotProvider = new TestingSlotProvider(ignore -> slotFutures.removeFirst());

	DirectScheduledExecutorService executorService = new DirectScheduledExecutorService();

	// execution graph that executes actions synchronously
	ExecutionGraph eg = TestingExecutionGraphBuilder
		.newBuilder()
		.setFutureExecutor(executorService)
		.setSlotProvider(slotProvider)
		.setBlobWriter(blobWriter)
		.build();

	checkJobOffloaded(eg);

	eg.start(ComponentMainThreadExecutorServiceAdapter.forMainThread());

	List<JobVertex> ordered = Arrays.asList(v1, v2);
	eg.attachJobGraph(ordered);

	// schedule, this triggers mock deployment
	eg.scheduleForExecution();

	Map<ExecutionAttemptID, Execution> executions = eg.getRegisteredExecutions();
	assertEquals(dop1 + dop2, executions.size());

	return new Tuple2<>(eg, executions);
}
 
Example 7
Source File: Networks.java    From beam with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a list of all distinct paths from roots of the network to leaves. The list can be in
 * arbitrary orders and can contain duplicate paths if there are multiple edges from two nodes.
 */
public static <NodeT, EdgeT> List<List<NodeT>> allPathsFromRootsToLeaves(
    Network<NodeT, EdgeT> network) {
  ArrayDeque<List<NodeT>> paths = new ArrayDeque<>();
  // Populate the list with all roots
  for (NodeT node : network.nodes()) {
    if (network.inDegree(node) == 0) {
      paths.add(ImmutableList.of(node));
    }
  }

  List<List<NodeT>> distinctPathsFromRootsToLeaves = new ArrayList<>();
  while (!paths.isEmpty()) {
    List<NodeT> path = paths.removeFirst();
    NodeT lastNode = path.get(path.size() - 1);
    if (network.outDegree(lastNode) == 0) {
      distinctPathsFromRootsToLeaves.add(new ArrayList<>(path));
    } else {
      for (EdgeT edge : network.outEdges(lastNode)) {
        paths.addFirst(
            ImmutableList.<NodeT>builder()
                .addAll(path)
                .add(network.incidentNodes(edge).target())
                .build());
      }
    }
  }
  return distinctPathsFromRootsToLeaves;
}
 
Example 8
Source File: ArrayDequeTest.java    From j2objc with Apache License 2.0 5 votes vote down vote up
/**
 * removeFirst() removes first element, or throws NSEE if empty
 */
public void testRemoveFirst() {
    ArrayDeque q = populatedDeque(SIZE);
    for (int i = 0; i < SIZE; ++i) {
        assertEquals(i, q.removeFirst());
    }
    try {
        q.removeFirst();
        shouldThrow();
    } catch (NoSuchElementException success) {}
    assertNull(q.peekFirst());
}
 
Example 9
Source File: ArrayDequeTest.java    From openjdk-jdk9 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * retainAll(c) retains only those elements of c and reports true if changed
 */
public void testRetainAll() {
    ArrayDeque q = populatedDeque(SIZE);
    ArrayDeque p = populatedDeque(SIZE);
    for (int i = 0; i < SIZE; ++i) {
        boolean changed = q.retainAll(p);
        assertEquals(changed, (i > 0));
        assertTrue(q.containsAll(p));
        assertEquals(SIZE - i, q.size());
        p.removeFirst();
    }
}
 
Example 10
Source File: AccessibilityNodeInfoUtils.java    From talkback with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the result of applying a filter using breadth-first traversal.
 *
 * @param node The root node to traverse from.
 * @param filter The filter to satisfy.
 * @return The first node reached via BFS traversal that satisfies the filter.
 */
public static AccessibilityNodeInfoCompat searchFromBfs(
    AccessibilityNodeInfoCompat node, Filter<AccessibilityNodeInfoCompat> filter) {
  if (node == null) {
    return null;
  }

  final ArrayDeque<AccessibilityNodeInfoCompat> queue = new ArrayDeque<>();
  Set<AccessibilityNodeInfoCompat> visitedNodes = new HashSet<>();

  queue.add(AccessibilityNodeInfoCompat.obtain(node));

  try {
    while (!queue.isEmpty()) {
      final AccessibilityNodeInfoCompat item = queue.removeFirst();
      visitedNodes.add(item);

      if (filter.accept(item)) {
        return item;
      }

      final int childCount = item.getChildCount();

      for (int i = 0; i < childCount; i++) {
        final AccessibilityNodeInfoCompat child = item.getChild(i);

        if (child != null && !visitedNodes.contains(child)) {
          queue.addLast(child);
        }
      }
      item.recycle();
    }
  } finally {
    while (!queue.isEmpty()) {
      queue.removeFirst().recycle();
    }
  }

  return null;
}
 
Example 11
Source File: ArrayDequeTest.java    From openjdk-jdk9 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * size changes when elements added and removed
 */
public void testSize() {
    ArrayDeque q = populatedDeque(SIZE);
    for (int i = 0; i < SIZE; ++i) {
        assertEquals(SIZE - i, q.size());
        q.removeFirst();
    }
    for (int i = 0; i < SIZE; ++i) {
        assertEquals(i, q.size());
        q.add(new Integer(i));
    }
}
 
Example 12
Source File: ArrayDequeTest.java    From j2objc with Apache License 2.0 5 votes vote down vote up
/**
 * retainAll(c) retains only those elements of c and reports true if changed
 */
public void testRetainAll() {
    ArrayDeque q = populatedDeque(SIZE);
    ArrayDeque p = populatedDeque(SIZE);
    for (int i = 0; i < SIZE; ++i) {
        boolean changed = q.retainAll(p);
        assertEquals(changed, (i > 0));
        assertTrue(q.containsAll(p));
        assertEquals(SIZE - i, q.size());
        p.removeFirst();
    }
}
 
Example 13
Source File: Dequeue.java    From Android-Cheat-sheet with Apache License 2.0 5 votes vote down vote up
public static void findMaximumSlidingWindow(int[] arr,
                                            int windowSize) {
    if (arr.length < windowSize) return;

    ArrayDeque<Integer> list = new ArrayDeque();
    for (int i = 0; i < windowSize; i++) {

        while (!list.isEmpty() && arr[i] >= arr[list.peekLast()]) {
            list.removeLast();
        }
        list.addLast(i);
    }

    System.out.print(arr[list.peekFirst()] + " ");


    for (int i = windowSize; i < arr.length; i++) {

        while (!list.isEmpty() && arr[i] >= arr[list.peekLast()]) {
            list.removeLast();
        }

        if (!list.isEmpty() && list.peekFirst() <= i - windowSize) {
            list.removeFirst();
        }

        list.addLast(i);
        System.out.print(arr[list.peekFirst()] + " ");
    }
}
 
Example 14
Source File: ArrayDequeTest.java    From j2objc with Apache License 2.0 5 votes vote down vote up
/**
 * isEmpty is true before add, false after
 */
public void testEmpty() {
    ArrayDeque q = new ArrayDeque();
    assertTrue(q.isEmpty());
    q.add(new Integer(1));
    assertFalse(q.isEmpty());
    q.add(new Integer(2));
    q.removeFirst();
    q.removeFirst();
    assertTrue(q.isEmpty());
}
 
Example 15
Source File: Networks.java    From beam with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a list of all distinct paths from roots of the network to leaves. The list can be in
 * arbitrary orders and can contain duplicate paths if there are multiple edges from two nodes.
 */
public static <NodeT, EdgeT> List<List<NodeT>> allPathsFromRootsToLeaves(
    Network<NodeT, EdgeT> network) {
  ArrayDeque<List<NodeT>> paths = new ArrayDeque<>();
  // Populate the list with all roots
  for (NodeT node : network.nodes()) {
    if (network.inDegree(node) == 0) {
      paths.add(ImmutableList.of(node));
    }
  }

  List<List<NodeT>> distinctPathsFromRootsToLeaves = new ArrayList<>();
  while (!paths.isEmpty()) {
    List<NodeT> path = paths.removeFirst();
    NodeT lastNode = path.get(path.size() - 1);
    if (network.outDegree(lastNode) == 0) {
      distinctPathsFromRootsToLeaves.add(new ArrayList<>(path));
    } else {
      for (EdgeT edge : network.outEdges(lastNode)) {
        paths.addFirst(
            ImmutableList.<NodeT>builder()
                .addAll(path)
                .add(network.incidentNodes(edge).target())
                .build());
      }
    }
  }
  return distinctPathsFromRootsToLeaves;
}
 
Example 16
Source File: SpliceAllRolesVTI.java    From spliceengine with GNU Affero General Public License v3.0 4 votes vote down vote up
@Override
public DataSet<ExecRow> getDataSet(SpliceOperation op, DataSetProcessor dsp, ExecRow execRow) throws StandardException {
    operationContext = dsp.createOperationContext(op);

    //Create an arraylist to store the list of roles
    ArrayList<ExecRow> items = new ArrayList<ExecRow>();

    Activation activation = op.getActivation();
    LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
    List<String> groupUsers = lcc.getCurrentGroupUser(activation);
    String currentUser = lcc.getCurrentUserId(activation);

    // populate the queue with root nodes in the role grant graph
    ArrayDeque<String> roleQueue = new ArrayDeque<>();
    roleQueue.add("PUBLIC");
    roleQueue.add(currentUser);
    if (groupUsers != null) {
        for (String user : groupUsers) {
            roleQueue.add(user);
        }
    }

    // get the role grant graph
    TransactionController tc = lcc.getTransactionExecute();
    DataDictionaryImpl dd = (DataDictionaryImpl)lcc.getDataDictionary();
    Map<String,List<RoleGrantDescriptor>> graph =
            dd.getRoleGrantGraph(tc, true, false);


    while (!roleQueue.isEmpty()) {
        String aRole = roleQueue.removeFirst();
        ExecRow valueRow = new ValueRow(1);
        valueRow.setColumn(1, new SQLVarchar(aRole));
        items.add(valueRow);

        List<RoleGrantDescriptor> outArcs = graph.get(aRole);
        if (outArcs != null) {
            for (RoleGrantDescriptor rd: outArcs) {
                roleQueue.add(rd.getRoleName());
            }
        }
    }

    return dsp.createDataSet(items.iterator());
}
 
Example 17
Source File: ExecutionGraphDeploymentTest.java    From flink with Apache License 2.0 4 votes vote down vote up
/**
 * Tests that a blocking batch job fails if there are not enough resources left to schedule the
 * succeeding tasks. This test case is related to [FLINK-4296] where finished producing tasks
 * swallow the fail exception when scheduling a consumer task.
 */
@Test
public void testNoResourceAvailableFailure() throws Exception {
	final JobID jobId = new JobID();
	JobVertex v1 = new JobVertex("source");
	JobVertex v2 = new JobVertex("sink");

	int dop1 = 1;
	int dop2 = 1;

	v1.setParallelism(dop1);
	v2.setParallelism(dop2);

	v1.setInvokableClass(BatchTask.class);
	v2.setInvokableClass(BatchTask.class);

	v2.connectNewDataSetAsInput(v1, DistributionPattern.POINTWISE, ResultPartitionType.BLOCKING);

	final ArrayDeque<CompletableFuture<LogicalSlot>> slotFutures = new ArrayDeque<>();
	for (int i = 0; i < dop1; i++) {
		slotFutures.addLast(CompletableFuture.completedFuture(new TestingLogicalSlotBuilder().createTestingLogicalSlot()));
	}

	final SlotProvider slotProvider = new TestingSlotProvider(ignore -> slotFutures.removeFirst());

	DirectScheduledExecutorService directExecutor = new DirectScheduledExecutorService();

	// execution graph that executes actions synchronously
	ExecutionGraph eg = createExecutionGraphWithoutQueuedScheduling(jobId, slotProvider, directExecutor, TestingUtils.defaultExecutor());

	eg.start(ComponentMainThreadExecutorServiceAdapter.forMainThread());

	checkJobOffloaded(eg);

	List<JobVertex> ordered = Arrays.asList(v1, v2);
	eg.attachJobGraph(ordered);

	// schedule, this triggers mock deployment
	eg.scheduleForExecution();

	ExecutionAttemptID attemptID = eg.getJobVertex(v1.getID()).getTaskVertices()[0].getCurrentExecutionAttempt().getAttemptId();
	eg.updateState(new TaskExecutionState(jobId, attemptID, ExecutionState.RUNNING));
	eg.updateState(new TaskExecutionState(jobId, attemptID, ExecutionState.FINISHED, null));

	assertEquals(JobStatus.FAILED, eg.getState());
}
 
Example 18
Source File: ActionRewindStrategy.java    From bazel with Apache License 2.0 4 votes vote down vote up
/**
 * Looks at each action in {@code actionsToCheck} and determines whether additional artifacts,
 * actions, and (in the case of {@link SkyframeAwareAction}s) other Skyframe nodes need to be
 * restarted. If this finds more actions to restart, those actions are recursively checked too.
 */
private void checkActions(
    ImmutableList<ActionAndLookupData> actionsToCheck,
    Environment env,
    MutableGraph<SkyKey> rewindGraph,
    ImmutableList.Builder<Action> additionalActionsToRestart)
    throws InterruptedException {

  ArrayDeque<ActionAndLookupData> uncheckedActions = new ArrayDeque<>(actionsToCheck);
  while (!uncheckedActions.isEmpty()) {
    ActionAndLookupData actionAndLookupData = uncheckedActions.removeFirst();
    ActionLookupData actionKey = actionAndLookupData.lookupData();
    Action action = actionAndLookupData.action();
    ArrayList<Artifact.DerivedArtifact> artifactsToCheck = new ArrayList<>();
    ArrayList<ActionLookupData> newlyDiscoveredActions = new ArrayList<>();

    if (action instanceof SkyframeAwareAction) {
      // This action depends on more than just its input artifact values. We need to also restart
      // the Skyframe subgraph it depends on, up to and including any artifacts, which may
      // aggregate multiple actions.
      addSkyframeAwareDepsAndGetNewlyVisitedArtifactsAndActions(
          rewindGraph,
          actionKey,
          (SkyframeAwareAction) action,
          artifactsToCheck,
          newlyDiscoveredActions);
    }

    if (action.mayInsensitivelyPropagateInputs()) {
      // Restarting this action won't recreate the missing input. We need to also restart this
      // action's non-source inputs and the actions which created those inputs.
      addPropagatingActionDepsAndGetNewlyVisitedArtifactsAndActions(
          rewindGraph, actionKey, action, artifactsToCheck, newlyDiscoveredActions);
    }

    for (ActionLookupData actionLookupData : newlyDiscoveredActions) {
      Action additionalAction =
          checkNotNull(
              ActionUtils.getActionForLookupData(env, actionLookupData), actionLookupData);
      additionalActionsToRestart.add(additionalAction);
      uncheckedActions.add(ActionAndLookupData.create(actionLookupData, additionalAction));
    }
    for (Artifact.DerivedArtifact artifact : artifactsToCheck) {
      Map<ActionLookupData, Action> actionMap = getActionsForLostArtifact(artifact, env);
      if (actionMap == null) {
        continue;
      }
      ImmutableList<ActionAndLookupData> newlyVisitedActions =
          addArtifactDepsAndGetNewlyVisitedActions(rewindGraph, artifact, actionMap);
      additionalActionsToRestart.addAll(actions(newlyVisitedActions));
      uncheckedActions.addAll(newlyVisitedActions);
    }
  }
}
 
Example 19
Source File: ExecutionGraphDeploymentTest.java    From Flink-CEPplus with Apache License 2.0 4 votes vote down vote up
/**
 * Tests that a blocking batch job fails if there are not enough resources left to schedule the
 * succeeding tasks. This test case is related to [FLINK-4296] where finished producing tasks
 * swallow the fail exception when scheduling a consumer task.
 */
@Test
public void testNoResourceAvailableFailure() throws Exception {
	final JobID jobId = new JobID();
	JobVertex v1 = new JobVertex("source");
	JobVertex v2 = new JobVertex("sink");

	int dop1 = 1;
	int dop2 = 1;

	v1.setParallelism(dop1);
	v2.setParallelism(dop2);

	v1.setInvokableClass(BatchTask.class);
	v2.setInvokableClass(BatchTask.class);

	v2.connectNewDataSetAsInput(v1, DistributionPattern.POINTWISE, ResultPartitionType.BLOCKING);

	final ArrayDeque<CompletableFuture<LogicalSlot>> slotFutures = new ArrayDeque<>();
	for (int i = 0; i < dop1; i++) {
		slotFutures.addLast(CompletableFuture.completedFuture(new TestingLogicalSlot()));
	}

	final SlotProvider slotProvider = new TestingSlotProvider(ignore -> slotFutures.removeFirst());

	final JobInformation jobInformation = new DummyJobInformation(
		jobId,
		"failing test job");

	DirectScheduledExecutorService directExecutor = new DirectScheduledExecutorService();

	// execution graph that executes actions synchronously
	ExecutionGraph eg = new ExecutionGraph(
		jobInformation,
		directExecutor,
		TestingUtils.defaultExecutor(),
		AkkaUtils.getDefaultTimeout(),
		new NoRestartStrategy(),
		new RestartAllStrategy.Factory(),
		slotProvider,
		ExecutionGraph.class.getClassLoader(),
		blobWriter,
		AkkaUtils.getDefaultTimeout());

	eg.start(TestingComponentMainThreadExecutorServiceAdapter.forMainThread());

	checkJobOffloaded(eg);

	eg.setQueuedSchedulingAllowed(false);

	List<JobVertex> ordered = Arrays.asList(v1, v2);
	eg.attachJobGraph(ordered);

	// schedule, this triggers mock deployment
	eg.scheduleForExecution();

	ExecutionAttemptID attemptID = eg.getJobVertex(v1.getID()).getTaskVertices()[0].getCurrentExecutionAttempt().getAttemptId();
	eg.updateState(new TaskExecutionState(jobId, attemptID, ExecutionState.RUNNING));
	eg.updateState(new TaskExecutionState(jobId, attemptID, ExecutionState.FINISHED, null));

	assertEquals(JobStatus.FAILED, eg.getState());
}
 
Example 20
Source File: GraphTaxonomy.java    From constellation with Apache License 2.0 4 votes vote down vote up
/**
     * Create a graph that represents the relationship between the taxa.
     * <p>
     * Vertices in the new graph are the taxa keys. A transaction in the new
     * graph from vertex A to vertex B represents all transactions from any
     * vertex in taxon A to any vertex in taxon B.
     * <p>
     * @throws java.lang.InterruptedException If the thread is interrupted.
     *
     * @return A Condensation representing the relationship between the taxa.
     *
     * TODO: sometimes its not worth adding the transactions.
     */
    public Condensation getCondensedGraph() throws InterruptedException {
//        final Map<Integer, Extent> taxonKeyToExtent = new HashMap<>();
        final Map<Integer, Integer> cVxIdToTaxonKey = new HashMap<>();
        final Map<Integer, Integer> taxonKeyToVxId = new HashMap<>();

        final GraphWriteMethods condensedGraph = new StoreGraph(wg.getSchema());
        final int cxAttr = VisualConcept.VertexAttribute.X.ensure(condensedGraph);
        final int cyAttr = VisualConcept.VertexAttribute.Y.ensure(condensedGraph);
        final int czAttr = VisualConcept.VertexAttribute.Z.ensure(condensedGraph);
        final int cxOrigId = condensedGraph.addAttribute(GraphElementType.VERTEX, FloatAttributeDescription.ATTRIBUTE_NAME, X_ORIG, X_ORIG, null, null);
        final int cyOrigId = condensedGraph.addAttribute(GraphElementType.VERTEX, FloatAttributeDescription.ATTRIBUTE_NAME, Y_ORIG, Y_ORIG, null, null);
        final int czOrigId = condensedGraph.addAttribute(GraphElementType.VERTEX, FloatAttributeDescription.ATTRIBUTE_NAME, Z_ORIG, Z_ORIG, null, null);
        final int cnRadiusAttr = VisualConcept.VertexAttribute.NODE_RADIUS.ensure(condensedGraph);
        final int cRadiusAttr = VisualConcept.VertexAttribute.LABEL_RADIUS.ensure(condensedGraph);

        // Add the vertices.
        // TODO: do these need to be sorted?
        for (final Integer k : getSortedTaxaKeys()) {
            if (Thread.interrupted()) {
                throw new InterruptedException();
            }
            if (taxa.get(k).isEmpty()) {
                continue;
            }

            final int cVxId = condensedGraph.addVertex();

            final BitSet vertices = new BitSet();
            for (Integer member : taxa.get(k)) {
                vertices.set(member);
            }

            // Figure out where and how big the new vertex will be.
            final Extent extent = Extent.getExtent(wg, vertices);

            // The condensation has the positions of the extents and the positions of the taxon key vertices.
            // The x,y,z will be modified, so remember them for repositioning later.
            condensedGraph.setFloatValue(cxAttr, cVxId, extent.getX());
            condensedGraph.setFloatValue(cyAttr, cVxId, extent.getY());
            condensedGraph.setFloatValue(czAttr, cVxId, extent.getZ());
            condensedGraph.setFloatValue(cxOrigId, cVxId, extent.getX());
            condensedGraph.setFloatValue(cyOrigId, cVxId, extent.getY());
            condensedGraph.setFloatValue(czOrigId, cVxId, extent.getZ());
            condensedGraph.setFloatValue(cnRadiusAttr, cVxId, extent.getNRadius());
            condensedGraph.setFloatValue(cRadiusAttr, cVxId, extent.getLRadius());
            cVxIdToTaxonKey.put(cVxId, k);
            taxonKeyToVxId.put(k, cVxId);
//            taxonKeyToExtent.put(k, extent);
        }

//        System.out.printf("@GT Condensation (nTaxa=%d) (vxCount %d->%d)\n", taxa.keySet().size(), graph.getVertexCount(), wg.getVertexCount());
        // Add the transactions.
        //        final long t0 = System.currentTimeMillis();
        // We search through all of the taxa to find sources,
        // but only look in the remaining taxa for destinations,
        // otherwise we end up with two transactions between each vertex.
        final ArrayDeque<Integer> sources = new ArrayDeque<>();
        sources.addAll(taxa.keySet());

        while (!sources.isEmpty()) {
            // If we already have a transaction from the current source to a particular destination,
            // don't add another one.
            final Set<Integer> found = new HashSet<>();

            final Integer src = sources.removeFirst();
            found.add(src);
            final Set<Integer> members = taxa.get(src);
            for (Integer mm : members) {
                if (Thread.interrupted()) {
                    throw new InterruptedException();
                }
                final int m = mm;
                final int nNeighbours = wg.getVertexNeighbourCount(m);
                for (int position = 0; position < nNeighbours; position++) {
                    final int nbId = wg.getVertexNeighbour(m, position);
                    final Integer dst = nodeToTaxa != null ? nodeToTaxa.get(nbId) : findTaxonContainingVertex(sources, nbId);
                    // Found the test for null was required to avoid issues
                    if (dst != null && dst != Graph.NOT_FOUND && !found.contains(dst)) {
                        //                            Debug.debug("condense src=%s(%s) dst=%s(%s)\n", src, taxonKeyToVxId.get(src), dst, taxonKeyToVxId.get(dst));
                        condensedGraph.addTransaction(taxonKeyToVxId.get(src), taxonKeyToVxId.get(dst), true);
                        found.add(dst);
                    }
                }
            }
        }

        return new Condensation(condensedGraph, cVxIdToTaxonKey);//, taxonKeyToExtent);
    }