Java Code Examples for java.util.Deque#push()

The following examples show how to use java.util.Deque#push() . 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: DatawaveInterpreter.java    From datawave with Apache License 2.0 6 votes vote down vote up
public Object visit(ASTOrNode node, Object data) {
    Deque<JexlNode> children = new ArrayDeque<>();
    Deque<JexlNode> stack = new ArrayDeque<>();
    stack.push(node);
    
    // iterative depth-first traversal of tree to avoid stack
    // overflow when traversing large or'd lists
    while (!stack.isEmpty()) {
        JexlNode currNode = stack.pop();
        
        if (currNode instanceof ASTOrNode) {
            for (int i = currNode.jjtGetNumChildren() - 1; i >= 0; i--) {
                stack.push(JexlASTHelper.dereference(currNode.jjtGetChild(i)));
            }
        } else {
            children.push(currNode);
        }
    }
    
    Object result = null;
    while (!arithmetic.toBoolean(result) && !children.isEmpty())
        result = interpretOr(children.pop().jjtAccept(this, data), result);
    
    return result;
}
 
Example 2
Source File: UncheckedFlatMapProof.java    From exonum-java-binding with Apache License 2.0 6 votes vote down vote up
/**
 * Folds two last entries in a contour and replaces them with the folded entry.
 * Returns an updated common prefix between two last entries in the contour.
 */
private Optional<DbKey> fold(Deque<MapProofEntry> contour, DbKey lastPrefix) {
  MapProofEntry lastEntry = contour.pop();
  MapProofEntry penultimateEntry = contour.pop();
  MapProofEntry newEntry =
      new MapProofEntry(lastPrefix, computeBranchHash(penultimateEntry, lastEntry));
  Optional<DbKey> commonPrefix;
  if (!contour.isEmpty()) {
    MapProofEntry previousEntry = contour.peek();
    commonPrefix = Optional.of(previousEntry.getDbKey().commonPrefix(lastPrefix));
  } else {
    commonPrefix = Optional.empty();
  }

  contour.push(newEntry);
  return commonPrefix;
}
 
Example 3
Source File: BlockSplitter.java    From jadx with Apache License 2.0 6 votes vote down vote up
private static void collectSuccessors(BlockNode startBlock, Set<BlockNode> toRemove) {
	Deque<BlockNode> stack = new ArrayDeque<>();
	stack.add(startBlock);
	while (!stack.isEmpty()) {
		BlockNode block = stack.pop();
		if (!toRemove.contains(block)) {
			toRemove.add(block);
			for (BlockNode successor : block.getSuccessors()) {
				if (toRemove.containsAll(successor.getPredecessors())) {
					stack.push(successor);
				}
			}
		}

	}
}
 
Example 4
Source File: DFSByIterative.java    From hellokoding-courses with MIT License 6 votes vote down vote up
static void dfsByIterative(GraphUndirectedByAdjacencyList g, int v) {
    boolean[] visited = new boolean[g.getV()];

    Deque<Integer> stack = new ArrayDeque<>();
    stack.push(v);

    while (!stack.isEmpty()) {
        v = stack.pop();

        if (!visited[v]) {
            visited[v] = true;
            System.out.printf("%d ", v);

            for(Integer w : g.getAdjacencyList().get(v)) {
                stack.push(w);
            }
        }
    }
}
 
Example 5
Source File: VerifyPreorderSerializationOfABinaryTree.java    From LeetCode-Sol-Res with MIT License 6 votes vote down vote up
/**
 * Stack.
 * Iterate through the string characters.
 * If it's a number, just push to stack.
 * If it's a '#', we need to figure out some sub situations:
 * 1) If the top of the stack is a number, then this '#' is the left child, just push it.
 * 2) If the top of the stack is a '#', then this '#' is the right child, we should pop the subtree.
 * 2.1) After the subtree is popped, if the stack top is still '#', it means the subtree should be popped again.
 * 2.2) If the stack top is a number, we need to add a '#' to mark that the next node knows it's a right child.
 * https://discuss.leetcode.com/topic/35973/java-intuitive-22ms-solution-with-stack
 */
public boolean isValidSerialization(String preorder) {
  Deque<String> stack = new ArrayDeque<>();
  String[] nodes = preorder.split(",");
  for (int i = 0; i < nodes.length; i++) {
    String curr = nodes[i];
    while ("#".equals(curr) && !stack.isEmpty() && "#".equals(stack.peek())) {
      stack.pop();
      if (stack.isEmpty()) {
        return false;
      }
      stack.pop();
    }
    stack.push(curr);
  }
  return stack.size() == 1 && "#".equals(stack.peek());
}
 
Example 6
Source File: ProfilerStateTest.java    From babar with Apache License 2.0 5 votes vote down vote up
@Test
public void parseNameOnly() throws Exception {
    Deque<AgentConfig.ConfigParser.State> states = new ArrayDeque<>();
    Map<String, Map<String, String>> profilersConfig = new HashMap<>();
    AgentConfig.ConfigParser.State state = new AgentConfig.ConfigParser.ProfilerState(states, profilersConfig);
    states.push(state);
    String s = state.parse("myProfiler");
    assertEquals("", s);
    assertEquals(0, profilersConfig.get("myProfiler").size());
    assertEquals(0, states.size());
}
 
Example 7
Source File: Find.java    From examples with Apache License 2.0 5 votes vote down vote up
/**
 * Parse a list of arguments to extract the {@link PathData} elements.
 * The input deque will be modified to remove the used elements.
 * @param args arguments to be parsed
 * @return list of {@link PathData} elements applicable to this command
 * @throws IOException if list can not be parsed
 */
private LinkedList<PathData> parsePathData(Deque<String> args) throws IOException {
  LinkedList<PathData> pathArgs = new LinkedList<PathData>();
  while(!args.isEmpty()) {
    String arg = args.pop();
    if(isExpression(arg) || "(".equals(arg) || (arg == null) || arg.startsWith("-")) {
      args.push(arg);
      return pathArgs;
    }
    pathArgs.addAll(expandArgument(arg));
  }
  return pathArgs;
}
 
Example 8
Source File: PSAbsCommand.java    From latexdraw with GNU General Public License v3.0 5 votes vote down vote up
@Override
public void execute(final Deque<Double> stack, final double x) {
	if(stack.isEmpty()) {
		throw new InvalidFormatPSFunctionException();
	}

	stack.push(Math.abs(stack.pop()));
}
 
Example 9
Source File: ProfilerStateTest.java    From babar with Apache License 2.0 5 votes vote down vote up
@Test
public void parseNameOtherText() throws Exception {
    Deque<AgentConfig.ConfigParser.State> states = new ArrayDeque<>();
    Map<String, Map<String, String>> profilersConfig = new HashMap<>();
    AgentConfig.ConfigParser.State state = new AgentConfig.ConfigParser.ProfilerState(states, profilersConfig);
    states.push(state);
    String s = state.parse("myProfiler,something");
    assertEquals(",something", s);
    assertEquals(0, profilersConfig.get("myProfiler").size());
    assertEquals(0, states.size());
}
 
Example 10
Source File: TestStack.java    From mini-jvm with GNU Lesser General Public License v3.0 5 votes vote down vote up
public static void main(String[] args) {
  Deque<Integer> stack = new ArrayDeque<>();

  Integer k1 = new Integer(1);
  stack.push(k1);

  int size = stack.size();
  Integer tmp = stack.pop();
  System.out.println(size);
  System.out.println(tmp);
}
 
Example 11
Source File: TaskHistoryWriter.java    From helios with Apache License 2.0 5 votes vote down vote up
private void putBack(TaskStatusEvent event) {
  final JobId key = event.getStatus().getJob().getId();
  final Deque<TaskStatusEvent> queue = getDeque(key);
  synchronized (queue) {
    if (queue.size() >= MAX_QUEUE_SIZE) {
      // already full, just toss the event
      return;
    }
    queue.push(event);
    count.incrementAndGet();
  }
}
 
Example 12
Source File: XMLHttpRequest.java    From htmlunit with Apache License 2.0 4 votes vote down vote up
/**
 * Sends the specified content to the server in an HTTP request and receives the response.
 * @param content the body of the message being sent with the request
 */
@JsxFunction
public void send(final Object content) {
    if (webRequest_ == null) {
        return;
    }
    prepareRequest(content);

    final Window w = getWindow();
    final WebWindow ww = w.getWebWindow();
    final WebClient client = ww.getWebClient();
    final AjaxController ajaxController = client.getAjaxController();
    final HtmlPage page = (HtmlPage) ww.getEnclosedPage();
    final boolean synchron = ajaxController.processSynchron(page, webRequest_, async_);
    if (synchron) {
        doSend(Context.getCurrentContext());
    }
    else {
        if (getBrowserVersion().hasFeature(XHR_FIRE_STATE_OPENED_AGAIN_IN_ASYNC_MODE)) {
            // quite strange but IE seems to fire state loading twice
            // in async mode (at least with HTML of the unit tests)
            setState(OPENED, Context.getCurrentContext());
        }

        // Create and start a thread in which to execute the request.
        final Scriptable startingScope = w;
        final ContextFactory cf = ((JavaScriptEngine) client.getJavaScriptEngine()).getContextFactory();
        final ContextAction<Object> action = new ContextAction<Object>() {
            @Override
            public Object run(final Context cx) {
                // KEY_STARTING_SCOPE maintains a stack of scopes
                @SuppressWarnings("unchecked")
                Deque<Scriptable> stack =
                        (Deque<Scriptable>) cx.getThreadLocal(JavaScriptEngine.KEY_STARTING_SCOPE);
                if (null == stack) {
                    stack = new ArrayDeque<>();
                    cx.putThreadLocal(JavaScriptEngine.KEY_STARTING_SCOPE, stack);
                }
                stack.push(startingScope);

                try {
                    doSend(cx);
                }
                finally {
                    stack.pop();
                }
                return null;
            }

            @Override
            public String toString() {
                return "XMLHttpRequest " + webRequest_.getHttpMethod() + " '" + webRequest_.getUrl() + "'";
            }
        };
        final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
                createJavascriptXMLHttpRequestJob(cf, action);
        if (LOG.isDebugEnabled()) {
            LOG.debug("Starting XMLHttpRequest thread for asynchronous request");
        }
        jobID_ = ww.getJobManager().addJob(job, page);
    }
}
 
Example 13
Source File: Util.java    From wildfly-core with GNU Lesser General Public License v2.1 4 votes vote down vote up
public static List<String> splitCommands(String line) {

        List<String> commands = null;
        int nextOpIndex = 0;
        Character expectedClosing = null;
        Deque<Character> expectedClosingStack = null;
        int i = 0;
        while(i < line.length()) {
            final char ch = line.charAt(i);
            if(ch == '\\') {
                ++i;//escape
            } else if(expectedClosing != null && expectedClosing == ch) {
                if(expectedClosingStack != null && !expectedClosingStack.isEmpty()) {
                    expectedClosing = expectedClosingStack.pop();
                } else {
                    expectedClosing = null;
                }
            } else {
                final Character matchingClosing = wrappingPairs.get(ch);
                if(matchingClosing != null) {
                    if(expectedClosing == null) {
                        expectedClosing = matchingClosing;
                    } else {
                        if(expectedClosingStack == null) {
                            expectedClosingStack = new ArrayDeque<Character>();
                        }
                        expectedClosingStack.push(expectedClosing);
                        expectedClosing = matchingClosing;
                    }
                } else if(expectedClosing == null && ch == ',') {
                    if(commands == null) {
                        commands = new ArrayList<String>();
                    }
                    commands.add(line.substring(nextOpIndex, i));
                    nextOpIndex = i + 1;
                }
            }
            ++i;
        }

        if(commands == null) {
            commands = Collections.singletonList(line);
        } else {
            commands.add(line.substring(nextOpIndex, i));
        }
        return commands;
    }
 
Example 14
Source File: ASTWriter.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 4 votes vote down vote up
private static void enqueueChildren(final Node node, final Class<?> nodeClass, final List<Field> children) {
    final Deque<Class<?>> stack = new ArrayDeque<>();

    /**
     * Here is some ugliness that can be overcome by proper ChildNode annotations
     * with proper orders. Right now we basically sort all classes up to Node
     * with super class first, as this often is the natural order, e.g. base
     * before index for an IndexNode.
     *
     * Also there are special cases as this is not true for UnaryNodes(lhs) and
     * BinaryNodes extends UnaryNode (with lhs), and TernaryNodes.
     *
     * TODO - generalize traversal with an order built on annotations and this
     * will go away.
     */
    Class<?> clazz = nodeClass;
    do {
        stack.push(clazz);
        clazz = clazz.getSuperclass();
    } while (clazz != null);

    if (node instanceof TernaryNode) {
        // HACK juggle "third"
        stack.push(stack.removeLast());
    }
    // HACK change operator order for BinaryNodes to get lhs first.
    final Iterator<Class<?>> iter = node instanceof BinaryNode ? stack.descendingIterator() : stack.iterator();

    while (iter.hasNext()) {
        final Class<?> c = iter.next();
        for (final Field f : c.getDeclaredFields()) {
            try {
                f.setAccessible(true);
                final Object child = f.get(node);
                if (child == null) {
                    continue;
                }

                if (child instanceof Node) {
                    children.add(f);
                } else if (child instanceof Collection) {
                    if (!((Collection<?>)child).isEmpty()) {
                        children.add(f);
                    }
                }
            } catch (final IllegalArgumentException | IllegalAccessException e) {
                return;
            }
        }
    }
}
 
Example 15
Source File: SpliteratorTestHelper.java    From openjdk-8 with GNU General Public License v2.0 4 votes vote down vote up
private static <T> void testSplitUntilNull(SplitNode<T> e) {
    // Use an explicit stack to avoid a StackOverflowException when testing a Spliterator
    // that when repeatedly split produces a right-balanced (and maybe degenerate) tree, or
    // for a spliterator that is badly behaved.
    Deque<SplitNode<T>> stack = new ArrayDeque<>();
    stack.push(e);

    int iteration = 0;
    while (!stack.isEmpty()) {
        assertTrue(iteration++ < MAXIMUM_STACK_CAPACITY, "Exceeded maximum stack modification count of 1 << 18");

        e = stack.pop();
        Spliterator<T> parentAndRightSplit = e.s;

        long parentEstimateSize = parentAndRightSplit.estimateSize();
        assertTrue(parentEstimateSize >= 0,
                   String.format("Split size estimate %d < 0", parentEstimateSize));

        long parentSize = parentAndRightSplit.getExactSizeIfKnown();
        Spliterator<T> leftSplit = parentAndRightSplit.trySplit();
        if (leftSplit == null) {
            parentAndRightSplit.forEachRemaining(e.c);
            continue;
        }

        assertSpliterator(leftSplit, e.rootCharacteristics);
        assertSpliterator(parentAndRightSplit, e.rootCharacteristics);

        if (parentEstimateSize != Long.MAX_VALUE && leftSplit.estimateSize() > 0
            && parentAndRightSplit.estimateSize() > 0) {
            assertTrue(leftSplit.estimateSize() < parentEstimateSize,
                       String.format("Left split size estimate %d >= parent split size estimate %d",
                                     leftSplit.estimateSize(), parentEstimateSize));
            assertTrue(parentAndRightSplit.estimateSize() < parentEstimateSize,
                       String.format("Right split size estimate %d >= parent split size estimate %d",
                                     leftSplit.estimateSize(), parentEstimateSize));
        }
        else {
            assertTrue(leftSplit.estimateSize() <= parentEstimateSize,
                       String.format("Left split size estimate %d > parent split size estimate %d",
                                     leftSplit.estimateSize(), parentEstimateSize));
            assertTrue(parentAndRightSplit.estimateSize() <= parentEstimateSize,
                       String.format("Right split size estimate %d > parent split size estimate %d",
                                     leftSplit.estimateSize(), parentEstimateSize));
        }

        long leftSize = leftSplit.getExactSizeIfKnown();
        long rightSize = parentAndRightSplit.getExactSizeIfKnown();
        if (parentSize >= 0 && leftSize >= 0 && rightSize >= 0)
            assertEquals(parentSize, leftSize + rightSize,
                         String.format("exact left split size %d + exact right split size %d != parent exact split size %d",
                                       leftSize, rightSize, parentSize));

        // Add right side to stack first so left side is popped off first
        stack.push(e.fromSplit(parentAndRightSplit));
        stack.push(e.fromSplit(leftSplit));
    }
}
 
Example 16
Source File: PivotFacetProcessor.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
/**
 * Process a single branch of refinement values for a specific pivot
 * @param pivotFields the ordered list of fields in this pivot
 * @param refinements the comma separate list of refinement values corresponding to each field in the pivot, or null if there are no refinements
 * @param statsFields List of {@link StatsField} instances to compute for each pivot value
 * @param facetQueries the list of facet queries hung under this pivot
 * @param facetRanges the list of facet ranges hung under this pivot
 */
private SimpleOrderedMap<List<NamedList<Object>>> processSingle
(List<String> pivotFields,
 String refinements,
 List<StatsField> statsFields,
 final ParsedParams parsed,
 List<FacetComponent.FacetBase> facetQueries,
 List<RangeFacetRequest> facetRanges) throws IOException {

  SolrIndexSearcher searcher = rb.req.getSearcher();
  SimpleOrderedMap<List<NamedList<Object>>> pivotResponse = new SimpleOrderedMap<>();

  String field = pivotFields.get(0);
  SchemaField sfield = searcher.getSchema().getField(field);
    
  Deque<String> fnames = new LinkedList<>();
  for( int i = pivotFields.size()-1; i>1; i-- ) {
    fnames.push( pivotFields.get(i) );
  }
  
  NamedList<Integer> facetCounts;
  Deque<String> vnames = new LinkedList<>();

  if (null != refinements) {
    // All values, split by the field they should go to
    List<String> refinementValuesByField
      = PivotFacetHelper.decodeRefinementValuePath(refinements);

    for( int i=refinementValuesByField.size()-1; i>0; i-- ) {
      vnames.push(refinementValuesByField.get(i));//Only for [1] and on
    }

    String firstFieldsValues = refinementValuesByField.get(0);

    facetCounts = new NamedList<>();
    facetCounts.add(firstFieldsValues,
                    getSubsetSize(parsed.docs, sfield, firstFieldsValues));
  } else {
    // no refinements needed
    facetCounts = this.getTermCountsForPivots(field, parsed);
  }
  
  if(pivotFields.size() > 1) {
    String subField = pivotFields.get(1);
    pivotResponse.add(parsed.key,
                      doPivots(facetCounts, field, subField, fnames, vnames, parsed, statsFields, facetQueries, facetRanges));
  } else {
    pivotResponse.add(parsed.key, doPivots(facetCounts, field, null, fnames, vnames, parsed, statsFields, facetQueries, facetRanges));
  }
  return pivotResponse;
}
 
Example 17
Source File: QueryPropertyMarkerVisitor.java    From datawave with Apache License 2.0 4 votes vote down vote up
@Override
public Object visit(ASTAndNode node, Object data) {
    // if this is an and node, and it is the first one we've
    // found, it is our potential candidate
    if (data == null) {
        List<JexlNode> siblingNodes = new ArrayList<>();
        
        Deque<JexlNode> siblings = new LinkedList<>();
        Deque<JexlNode> stack = new LinkedList<>();
        stack.push(node);
        
        // for the purposes of this method, nested and nodes are
        // ignored, and their children are handled as direct children
        // of the parent and node.
        while (!stack.isEmpty()) {
            JexlNode descendant = stack.pop();
            
            if (descendant instanceof ASTAndNode) {
                for (JexlNode sibling : children(descendant))
                    stack.push(sibling);
            } else {
                siblings.push(descendant);
            }
        }
        
        // check each child to see if we found our identifier, and
        // save off the siblings as potential source nodes
        for (JexlNode child : siblings) {
            
            // don't look for identifiers if we already found what we were looking for
            if (!identifierFound) {
                Set<String> foundIdentifiers = new HashSet<>();
                child.jjtAccept(this, foundIdentifiers);
                
                foundIdentifiers.retainAll(typeIdentifiers);
                
                // if we found our identifier, proceed to the next child node
                if (!foundIdentifiers.isEmpty()) {
                    identifierFound = true;
                    continue;
                }
            }
            
            siblingNodes.add(child);
        }
        
        if (identifierFound)
            sourceNodes = siblingNodes;
    }
    return null;
}
 
Example 18
Source File: SpliteratorTestHelper.java    From streamsupport with GNU General Public License v2.0 4 votes vote down vote up
private static <T> void testSplitUntilNull(SplitNode<T> e) {
    // Use an explicit stack to avoid a StackOverflowException when testing a Spliterator
    // that when repeatedly split produces a right-balanced (and maybe degenerate) tree, or
    // for a spliterator that is badly behaved.
    Deque<SplitNode<T>> stack = new ArrayDeque<>();
    stack.push(e);

    int iteration = 0;
    while (!stack.isEmpty()) {
        assertTrue(iteration++ < MAXIMUM_STACK_CAPACITY, "Exceeded maximum stack modification count of 1 << 18");

        e = stack.pop();
        Spliterator<T> parentAndRightSplit = e.s;

        long parentEstimateSize = parentAndRightSplit.estimateSize();
        assertTrue(parentEstimateSize >= 0,
                   String.format("Split size estimate %d < 0", parentEstimateSize));

        long parentSize = parentAndRightSplit.getExactSizeIfKnown();
        Spliterator<T> leftSplit = parentAndRightSplit.trySplit();
        if (leftSplit == null) {
            parentAndRightSplit.forEachRemaining(e.c);
            continue;
        }

        assertSpliterator(leftSplit, e.rootCharacteristics);
        assertSpliterator(parentAndRightSplit, e.rootCharacteristics);

        if (parentEstimateSize != Long.MAX_VALUE && leftSplit.estimateSize() > 0
            && parentAndRightSplit.estimateSize() > 0) {
            assertTrue(leftSplit.estimateSize() < parentEstimateSize,
                       String.format("Left split size estimate %d >= parent split size estimate %d",
                                     leftSplit.estimateSize(), parentEstimateSize));
            assertTrue(parentAndRightSplit.estimateSize() < parentEstimateSize,
                       String.format("Right split size estimate %d >= parent split size estimate %d",
                                     leftSplit.estimateSize(), parentEstimateSize));
        }
        else {
            assertTrue(leftSplit.estimateSize() <= parentEstimateSize,
                       String.format("Left split size estimate %d > parent split size estimate %d",
                                     leftSplit.estimateSize(), parentEstimateSize));
            assertTrue(parentAndRightSplit.estimateSize() <= parentEstimateSize,
                       String.format("Right split size estimate %d > parent split size estimate %d",
                                     leftSplit.estimateSize(), parentEstimateSize));
        }

        long leftSize = leftSplit.getExactSizeIfKnown();
        long rightSize = parentAndRightSplit.getExactSizeIfKnown();
        if (parentSize >= 0 && leftSize >= 0 && rightSize >= 0)
            assertEquals(parentSize, leftSize + rightSize,
                         String.format("exact left split size %d + exact right split size %d != parent exact split size %d",
                                       leftSize, rightSize, parentSize));

        // Add right side to stack first so left side is popped off first
        stack.push(e.fromSplit(parentAndRightSplit));
        stack.push(e.fromSplit(leftSplit));
    }
}
 
Example 19
Source File: Stu3StructureDefinitions.java    From bunsen with Apache License 2.0 4 votes vote down vote up
private <T> T transformRoot(DefinitionVisitor<T> visitor,
    StructureDefinition definition,
    List<StructureDefinition> containedDefinitions,
    Deque<QualifiedPath> stack) {

  ElementDefinition definitionRootElement = definition.getSnapshot().getElementFirstRep();

  List<ElementDefinition> definitions = definition.getSnapshot().getElement();

  ElementDefinition root = definitions.get(0);

  stack.push(new QualifiedPath(definition.getUrl(), definitionRootElement.getPath()));

  List<StructureField<T>> childElements = transformChildren(visitor,
      definition,
      definitions,
      stack,
      root);

  // If there are contained definitions, create a Resource Container StructureField
  if (containedDefinitions.size() > 0) {

    StructureField<T> containedElement = transformContained(visitor,
        definition,
        containedDefinitions,
        stack,
        root);

    // Replace default StructureField with constructed Resource Container StructureField
    childElements.set(5, containedElement);
  }

  stack.pop();

  String rootName = elementName(root);

  return visitor.visitComposite(rootName,
      rootName,
      rootName,
      definition.getUrl(),
      childElements);
}
 
Example 20
Source File: SpliteratorTraversingAndSplittingTest.java    From jdk8u60 with GNU General Public License v2.0 4 votes vote down vote up
private static <T> void testSplitUntilNull(SplitNode<T> e) {
    // Use an explicit stack to avoid a StackOverflowException when testing a Spliterator
    // that when repeatedly split produces a right-balanced (and maybe degenerate) tree, or
    // for a spliterator that is badly behaved.
    Deque<SplitNode<T>> stack = new ArrayDeque<>();
    stack.push(e);

    int iteration = 0;
    while (!stack.isEmpty()) {
        assertTrue(iteration++ < MAXIMUM_STACK_CAPACITY, "Exceeded maximum stack modification count of 1 << 18");

        e = stack.pop();
        Spliterator<T> parentAndRightSplit = e.s;

        long parentEstimateSize = parentAndRightSplit.estimateSize();
        assertTrue(parentEstimateSize >= 0,
                   String.format("Split size estimate %d < 0", parentEstimateSize));

        long parentSize = parentAndRightSplit.getExactSizeIfKnown();
        Spliterator<T> leftSplit = parentAndRightSplit.trySplit();
        if (leftSplit == null) {
            parentAndRightSplit.forEachRemaining(e.c);
            continue;
        }

        assertSpliterator(leftSplit, e.rootCharacteristics);
        assertSpliterator(parentAndRightSplit, e.rootCharacteristics);

        if (parentEstimateSize != Long.MAX_VALUE && leftSplit.estimateSize() > 0 && parentAndRightSplit.estimateSize() > 0) {
            assertTrue(leftSplit.estimateSize() < parentEstimateSize,
                       String.format("Left split size estimate %d >= parent split size estimate %d", leftSplit.estimateSize(), parentEstimateSize));
            assertTrue(parentAndRightSplit.estimateSize() < parentEstimateSize,
                       String.format("Right split size estimate %d >= parent split size estimate %d", leftSplit.estimateSize(), parentEstimateSize));
        }
        else {
            assertTrue(leftSplit.estimateSize() <= parentEstimateSize,
                       String.format("Left split size estimate %d > parent split size estimate %d", leftSplit.estimateSize(), parentEstimateSize));
            assertTrue(parentAndRightSplit.estimateSize() <= parentEstimateSize,
                       String.format("Right split size estimate %d > parent split size estimate %d", leftSplit.estimateSize(), parentEstimateSize));
        }

        long leftSize = leftSplit.getExactSizeIfKnown();
        long rightSize = parentAndRightSplit.getExactSizeIfKnown();
        if (parentSize >= 0 && leftSize >= 0 && rightSize >= 0)
            assertEquals(parentSize, leftSize + rightSize,
                         String.format("exact left split size %d + exact right split size %d != parent exact split size %d",
                                       leftSize, rightSize, parentSize));

        // Add right side to stack first so left side is popped off first
        stack.push(e.fromSplit(parentAndRightSplit));
        stack.push(e.fromSplit(leftSplit));
    }
}