下面列出了java.util.ArrayDeque#pop ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static void propagateAdd(ArrayDeque<LightNode> lightQueue, LightWorldSection w) {
if (lightQueue.isEmpty()) return;
while (!lightQueue.isEmpty()) {
LightNode n = lightQueue.pop();
int x = n.x;
int y = n.y;
int z = n.z;
int l = n.l;
if (l <= 1) continue;
tryPropagateAdd(lightQueue, w, x - 1, y, z, l);
tryPropagateAdd(lightQueue, w, x + 1, y, z, l);
tryPropagateAdd(lightQueue, w, x, y, z - 1, l);
tryPropagateAdd(lightQueue, w, x, y, z + 1, l);
if (y > 0) tryPropagateAdd(lightQueue, w, x, y - 1, z, l);
tryPropagateAdd(lightQueue, w, x, y + 1, z, l);
}
}
static String extractTypeFroVariableBase(VariableBase varBase, Map<String, AssignmentImpl> allAssignments) {
ArrayDeque<VariableBase> stack = new ArrayDeque<>();
String typeName = null;
createVariableBaseChain(varBase, stack);
while (!stack.isEmpty() && stack.peek() != null) {
varBase = stack.pop();
String tmpType = extractVariableTypeFromVariableBase(varBase, allAssignments);
if (tmpType == null) {
typeName = null;
break;
}
if (typeName == null) {
typeName = tmpType;
} else {
typeName += tmpType;
}
}
return typeName; //extractVariableTypeFromVariableBase(varBase);
}
/**
* Locate a late inline call site: find, in this instance's
* {@linkplain #calls call sites}, the one furthest down the given call
* stack.
*
* Multiple chains of identical call sites with the same method name / bci
* combination are possible, so we have to try them all until we find the
* late inline call site that has a matching inline ID.
*
* @return a matching call site, or {@code null} if none was found.
*/
public CallSite findCallSite(ArrayDeque<CallSite> sites) {
if (calls == null) {
return null;
}
CallSite site = sites.pop();
for (CallSite c : calls) {
if (c.matches(site)) {
if (!sites.isEmpty()) {
CallSite res = c.findCallSite(sites);
if (res != null) {
sites.push(site);
return res;
}
} else {
sites.push(site);
return c;
}
}
}
sites.push(site);
return null;
}
void computeIndirectRelationships() {
ArrayDeque<InheritanceGraphNode> toVisit = new ArrayDeque<>();
toVisit.addAll(directChildren);
while (!toVisit.isEmpty()) {
InheritanceGraphNode child = toVisit.pop();
children.add(child);
toVisit.addAll(child.directChildren);
}
toVisit.addAll(directParents);
while (!toVisit.isEmpty()) {
InheritanceGraphNode parent = toVisit.pop();
parents.add(parent);
toVisit.addAll(parent.directParents);
}
}
@Override
public List<ValidationMessage> validate(Archetype archetype) {
List<ValidationMessage> result = new ArrayList<>();
beginValidation(archetype);
ArrayDeque<CObject> workList = new ArrayDeque<>();
workList.add(archetype.getDefinition());
while(!workList.isEmpty()) {
CObject cObject = workList.pop();
result.addAll(validate(cObject));
for(CAttribute attribute: cObject.getAttributes()) {
result.addAll(validate(attribute));
workList.addAll(attribute.getChildren());
}
}
result.addAll(endValidation(archetype));
return result;
}
private static void propagateAdd(ArrayDeque<LightNode> lightQueue, LightWorldSection w) {
if (lightQueue.isEmpty()) return;
while (!lightQueue.isEmpty()) {
LightNode n = lightQueue.pop();
int x = n.x;
int y = n.y;
int z = n.z;
int l = n.l;
if (l <= 1) continue;
tryPropagateAdd(lightQueue, w, x - 1, y, z, l - 1);
tryPropagateAdd(lightQueue, w, x + 1, y, z, l - 1);
tryPropagateAdd(lightQueue, w, x, y, z - 1, l - 1);
tryPropagateAdd(lightQueue, w, x, y, z + 1, l - 1);
if (y > 0) tryPropagateAdd(lightQueue, w, x, y - 1, z, l); // go down without loss in strength
tryPropagateAdd(lightQueue, w, x, y + 1, z, l - 1);
}
}
/**
* Creates an extension from a {@code path}.
*
* @param loadImport an import label representing an extension to load.
*/
private ExtensionData loadExtension(LoadImport loadImport)
throws IOException, BuildFileParseException, InterruptedException {
ExtensionData extension = null;
ArrayDeque<ExtensionLoadState> work = new ArrayDeque<>();
work.push(
new ExtensionLoadState(
loadImport, getImportPath(loadImport.getLabel(), loadImport.getImport())));
while (!work.isEmpty()) {
ExtensionLoadState load = work.peek();
extension =
lookupExtensionForImport(load.getPath(), load.getSkylarkImport().getImportString());
if (extension != null) {
// It's possible that some lower level dependencies already loaded
// this work item. We're done with it, so pop the queue.
work.pop();
continue;
}
// Load BuildFileAST if needed.
boolean astLoaded = maybeLoadAST(load);
boolean haveUnsatisfiedDeps = astLoaded && processExtensionDependencies(load, work);
// NB: If we have unsatisfied dependencies, we don't do anything;
// more importantly we do not pop the work queue in this case.
// This load is kept on the queue until all of its dependencies are satisfied.
if (!haveUnsatisfiedDeps) {
// We are done with this load; build it and cache it.
work.removeFirst();
extension = buildExtensionData(load);
extensionDataCache.put(load.getPath(), extension);
}
}
Preconditions.checkNotNull(extension);
return extension;
}
/**
* pop() removes next element, or throws NSEE if empty
*/
public void testPop() {
ArrayDeque q = populatedDeque(SIZE);
for (int i = 0; i < SIZE; ++i) {
assertEquals(i, q.pop());
}
try {
q.pop();
shouldThrow();
} catch (NoSuchElementException success) {}
}
/**
* Visits all nodes in the resource tree bellow the given resource using
* depth-first search.
*/
public void depthFirstSearch(Context context, SearchResultVisitor visitor, Resource root) {
ArrayDeque<SearchResults.Result> stack = Queues.newArrayDeque();
// Build an instance of a SearchResult for the root resource
// but don't invoke the visitor with it
boolean skipFirstVisit = true;
SearchResults initialResults = new SearchResults();
initialResults.addResult(root, new ArrayList<String>(0));
stack.add(initialResults.iterator().next());
while (!stack.isEmpty()) {
SearchResults.Result r = stack.pop();
if (skipFirstVisit) {
skipFirstVisit = false;
} else {
if (!visitor.visit(r)) {
return;
}
}
// Reverse the order of the results so we walk the left-most
// branches first
ImmutableList<SearchResults.Result> results = ImmutableList.copyOf(m_searcher.search(
context, matchKeyAndValue(Constants.PARENT_TERM_FIELD, r.getResource().getId())));
for (SearchResults.Result result : results.reverse()) {
stack.push(result);
}
}
}
/**
* Parses the text payload of a WebVTT Cue and applies modifications on {@link WebvttCue.Builder}.
*
* @param id Id of the cue, {@code null} if it is not present.
* @param markup The markup text to be parsed.
* @param styles List of styles defined by the CSS style blocks preceding the cues.
* @param builder Output builder.
*/
/* package */ static void parseCueText(
@Nullable String id, String markup, WebvttCue.Builder builder, List<WebvttCssStyle> styles) {
SpannableStringBuilder spannedText = new SpannableStringBuilder();
ArrayDeque<StartTag> startTagStack = new ArrayDeque<>();
List<StyleMatch> scratchStyleMatches = new ArrayList<>();
int pos = 0;
while (pos < markup.length()) {
char curr = markup.charAt(pos);
switch (curr) {
case CHAR_LESS_THAN:
if (pos + 1 >= markup.length()) {
pos++;
break; // avoid ArrayOutOfBoundsException
}
int ltPos = pos;
boolean isClosingTag = markup.charAt(ltPos + 1) == CHAR_SLASH;
pos = findEndOfTag(markup, ltPos + 1);
boolean isVoidTag = markup.charAt(pos - 2) == CHAR_SLASH;
String fullTagExpression = markup.substring(ltPos + (isClosingTag ? 2 : 1),
isVoidTag ? pos - 2 : pos - 1);
if (fullTagExpression.trim().isEmpty()) {
continue;
}
String tagName = getTagName(fullTagExpression);
if (!isSupportedTag(tagName)) {
continue;
}
if (isClosingTag) {
StartTag startTag;
do {
if (startTagStack.isEmpty()) {
break;
}
startTag = startTagStack.pop();
applySpansForTag(id, startTag, spannedText, styles, scratchStyleMatches);
} while(!startTag.name.equals(tagName));
} else if (!isVoidTag) {
startTagStack.push(StartTag.buildStartTag(fullTagExpression, spannedText.length()));
}
break;
case CHAR_AMPERSAND:
int semiColonEndIndex = markup.indexOf(CHAR_SEMI_COLON, pos + 1);
int spaceEndIndex = markup.indexOf(CHAR_SPACE, pos + 1);
int entityEndIndex = semiColonEndIndex == -1 ? spaceEndIndex
: (spaceEndIndex == -1 ? semiColonEndIndex
: Math.min(semiColonEndIndex, spaceEndIndex));
if (entityEndIndex != -1) {
applyEntity(markup.substring(pos + 1, entityEndIndex), spannedText);
if (entityEndIndex == spaceEndIndex) {
spannedText.append(" ");
}
pos = entityEndIndex + 1;
} else {
spannedText.append(curr);
pos++;
}
break;
default:
spannedText.append(curr);
pos++;
break;
}
}
// apply unclosed tags
while (!startTagStack.isEmpty()) {
applySpansForTag(id, startTagStack.pop(), spannedText, styles, scratchStyleMatches);
}
applySpansForTag(id, StartTag.buildWholeCueVirtualTag(), spannedText, styles,
scratchStyleMatches);
builder.setText(spannedText);
}
/**
* Parses the text payload of a WebVTT Cue and applies modifications on {@link WebvttCue.Builder}.
*
* @param id Id of the cue, {@code null} if it is not present.
* @param markup The markup text to be parsed.
* @param styles List of styles defined by the CSS style blocks preceeding the cues.
* @param builder Output builder.
*/
/* package */ static void parseCueText(String id, String markup, WebvttCue.Builder builder,
List<WebvttCssStyle> styles) {
SpannableStringBuilder spannedText = new SpannableStringBuilder();
ArrayDeque<StartTag> startTagStack = new ArrayDeque<>();
List<StyleMatch> scratchStyleMatches = new ArrayList<>();
int pos = 0;
while (pos < markup.length()) {
char curr = markup.charAt(pos);
switch (curr) {
case CHAR_LESS_THAN:
if (pos + 1 >= markup.length()) {
pos++;
break; // avoid ArrayOutOfBoundsException
}
int ltPos = pos;
boolean isClosingTag = markup.charAt(ltPos + 1) == CHAR_SLASH;
pos = findEndOfTag(markup, ltPos + 1);
boolean isVoidTag = markup.charAt(pos - 2) == CHAR_SLASH;
String fullTagExpression = markup.substring(ltPos + (isClosingTag ? 2 : 1),
isVoidTag ? pos - 2 : pos - 1);
String tagName = getTagName(fullTagExpression);
if (tagName == null || !isSupportedTag(tagName)) {
continue;
}
if (isClosingTag) {
StartTag startTag;
do {
if (startTagStack.isEmpty()) {
break;
}
startTag = startTagStack.pop();
applySpansForTag(id, startTag, spannedText, styles, scratchStyleMatches);
} while(!startTag.name.equals(tagName));
} else if (!isVoidTag) {
startTagStack.push(StartTag.buildStartTag(fullTagExpression, spannedText.length()));
}
break;
case CHAR_AMPERSAND:
int semiColonEndIndex = markup.indexOf(CHAR_SEMI_COLON, pos + 1);
int spaceEndIndex = markup.indexOf(CHAR_SPACE, pos + 1);
int entityEndIndex = semiColonEndIndex == -1 ? spaceEndIndex
: (spaceEndIndex == -1 ? semiColonEndIndex
: Math.min(semiColonEndIndex, spaceEndIndex));
if (entityEndIndex != -1) {
applyEntity(markup.substring(pos + 1, entityEndIndex), spannedText);
if (entityEndIndex == spaceEndIndex) {
spannedText.append(" ");
}
pos = entityEndIndex + 1;
} else {
spannedText.append(curr);
pos++;
}
break;
default:
spannedText.append(curr);
pos++;
break;
}
}
// apply unclosed tags
while (!startTagStack.isEmpty()) {
applySpansForTag(id, startTagStack.pop(), spannedText, styles, scratchStyleMatches);
}
applySpansForTag(id, StartTag.buildWholeCueVirtualTag(), spannedText, styles,
scratchStyleMatches);
builder.setText(spannedText);
}
/**
* Parses FTS options from the create statement of an FTS table.
*
* This method assumes the given create statement is a valid well-formed SQLite statement as
* defined in the <a href="https://www.sqlite.org/lang_createvtab.html">CREATE VIRTUAL TABLE
* syntax diagram</a>.
*
* @param createStatement the "CREATE VIRTUAL TABLE" statement.
* @return the set of FTS option key and values in the create statement.
*/
@VisibleForTesting
@SuppressWarnings("WeakerAccess") /* synthetic access */
static Set<String> parseOptions(String createStatement) {
if (createStatement.isEmpty()) {
return new HashSet<>();
}
// Module arguments are within the parenthesis followed by the module name.
String argsString = createStatement.substring(
createStatement.indexOf('(') + 1,
createStatement.lastIndexOf(')'));
// Split the module argument string by the comma delimiter, keeping track of quotation so
// so that if the delimiter is found within a string literal we don't substring at the wrong
// index. SQLite supports four ways of quoting keywords, see:
// https://www.sqlite.org/lang_keywords.html
List<String> args = new ArrayList<>();
ArrayDeque<Character> quoteStack = new ArrayDeque<>();
int lastDelimiterIndex = -1;
for (int i = 0; i < argsString.length(); i++) {
char c = argsString.charAt(i);
switch (c) {
case '\'':
case '"':
case '`':
if (quoteStack.isEmpty()) {
quoteStack.push(c);
} else if (quoteStack.peek() == c) {
quoteStack.pop();
}
break;
case '[':
if (quoteStack.isEmpty()) {
quoteStack.push(c);
}
break;
case ']':
if (!quoteStack.isEmpty() && quoteStack.peek() == '[') {
quoteStack.pop();
}
break;
case ',':
if (quoteStack.isEmpty()) {
args.add(argsString.substring(lastDelimiterIndex + 1, i).trim());
lastDelimiterIndex = i;
}
break;
}
}
args.add(argsString.substring(lastDelimiterIndex + 1).trim()); // Add final argument.
// Match args against valid options, otherwise they are column definitions.
HashSet<String> options = new HashSet<>();
for (String arg : args) {
for (String validOption : FTS_OPTIONS) {
if (arg.startsWith(validOption)) {
options.add(arg);
}
}
}
return options;
}
private void toMarkdown(Metadata metadata, ArrayDeque<Metadata> parents, int indent) {
parents.push(metadata);
try {
switch (metadata.type()) {
case RULE:
rule(metadata, parents, indent);
break;
case WHEN:
when(metadata, parents, indent);
break;
case BINARY_PREDICATE:
case TEMPLATE_PARAM:
binary(metadata, parents, indent);
break;
case LEAF_PREDICATE:
case FIELD_PREDICATE:
case LEAF_VALUE:
case MAPPING_LEAF:
case TEMPLATE_IDENTIFIER:
leaf(metadata, parents, indent);
break;
case UNARY_PREDICATE:
unary(metadata, parents, indent);
break;
case FIELD_PREDICATE_MATCH_ANY:
case NARY_PREDICATE:
nary(metadata, parents, indent);
break;
case SINGLE_MAPPING:
singleMapping(metadata, parents, indent);
break;
case MULTIPLE_MAPPING:
multipleMapping(metadata, parents, indent);
break;
case TYPE_CONVERTER:
typeConverter(metadata, parents, indent);
case THEN_MAPPING:
case ELSE_MAPPING:
case MAPPING_INPUT:
mappingFragment(metadata, parents, indent);
break;
default:
throw new IllegalStateException(metadata.type().name());
}
} finally {
parents.pop();
}
}
private void toHtml(Metadata metadata, ArrayDeque<Metadata> parents) {
parents.push(metadata);
try {
switch (metadata.type()) {
case RULE:
rule(metadata, parents);
break;
case WHEN:
when(metadata, parents);
break;
case BINARY_PREDICATE:
case TEMPLATE_PARAM:
binary(metadata, parents);
break;
case LEAF_PREDICATE:
case FIELD_PREDICATE:
case LEAF_VALUE:
case MAPPING_LEAF:
case TEMPLATE_IDENTIFIER:
leaf(metadata, parents);
break;
case MAPPING_LEAF_ITERABLE:
iterable(metadata, parents);
break;
case TYPE_CONVERTER:
typeConverter(metadata, parents);
break;
case UNARY_PREDICATE:
unary(metadata, parents);
break;
case NARY_PREDICATE:
case MULTIPLE_MAPPING:
case THEN_MAPPING:
case ELSE_MAPPING:
nary(metadata, parents);
break;
case MAPPING_INPUT:
mappingInput(metadata, parents);
break;
case FIELD_PREDICATE_MATCH_ANY:
iterable(metadata, parents);
// fieldMatchAny(metadata, parents);
break;
case SINGLE_MAPPING:
singleMapping(metadata, parents);
break;
default:
throw new IllegalStateException(metadata.type().name());
}
} finally {
parents.pop();
}
}
@Override
public void setUnspecifiedElementNamespace(final String namespace) {
ArrayDeque<String> namespaces = this.unspecifiedNamespaces;
namespaces.pop();
namespaces.push(namespace == null ? NO_NAMESPACE : namespace);
}
/**
* Calculate the block type. The value type that is on the stack after the block.
*
* @param instructions
* the instructions of the function
*/
void calculateBlockType( List<WasmInstruction> instructions ) {
for( int i = size() - 1; i >= 0; i-- ) {
BranchNode branch = get( i );
branch.calculateBlockType( instructions );
}
if( startBlock != null && startBlock.getOperation() == WasmBlockOperator.IF ) {
try {
ArrayDeque<AnyType> stack = new ArrayDeque<>();
stack.push( ValueType.empty );
INSTRUCTIONS: for( int i = startIdx; i < instructions.size(); i++ ) {
WasmInstruction instr = instructions.get( i );
int codePos = instr.getCodePosition();
if( codePos >= endPos ) {
break;
}
int popCount = instr.getPopCount();
for( int p = 0; p < popCount; p++ ) {
stack.pop();
}
AnyType pushValue = instr.getPushValueType();
if( pushValue != null ) {
stack.push( pushValue );
}
if( instr.getType() == Type.Block ) {
switch( ((WasmBlockInstruction)instr).getOperation() ) {
case RETURN:
// set "empty" block type
while( stack.size() > 1 ) {
stack.pop();
}
break INSTRUCTIONS;
case IF:
case BLOCK:
case LOOP:
case TRY:
// skip the content of the block, important to not count ELSE blocks
i = findEndInstruction( instructions, i );
break;
}
}
}
startBlock.setData( stack.pop() );
} catch( Throwable th ) {
throw WasmException.create( th, startBlock.getLineNumber() );
}
}
}
public static Class extendClass(Class<?> extend, final LuaTable delegations, Class<?>... inherit) {
long startTime = System.nanoTime();
ArrayDeque<Class> toCheck = new ArrayDeque<Class>();
toCheck.add(extend);
toCheck.addAll(Arrays.asList(inherit));
while (!toCheck.isEmpty()) {
Class check = toCheck.pop();
for (Method method : check.getDeclaredMethods()) {
if (Modifier.isAbstract(method.getModifiers())) {
if (delegations.get(method.getName()).isnil())
throw new DynamicDelegationError("No delegation for abstract method " + method);
}
}
check = check.getSuperclass();
if (check != null && check != Object.class) toCheck.add(check);
}
try {
ReceiverTypeDefinition<?> build = b.subclass(extend).implement(inherit)
.method(not(isConstructor()).and(isAbstract())).intercept(MethodDelegation.to(new AbstractInterceptor(delegations)));
if (!delegations.get("__new__").isnil()) {
build = build.constructor(isConstructor()).intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.to(new ConstructorInterceptor(delegations))));
}
Junction<MethodDescription> publicMethods = not(isConstructor().or(isAbstract())).and(isPublic()).and(new ElementMatcher<MethodDescription>() {
@Override
public boolean matches(MethodDescription target) {
return !delegations.get(target.getName()).isnil();
}
});
build = build.method(publicMethods).intercept(MethodDelegation.to(new PublicInterceptor(delegations)));
Unloaded unloaded = build.make();
Loaded loaded = Compatibility.get().load(unloaded);
Class c = loaded.getLoaded();
Log.debug("Created dynamic class " + c.getName() + " in " + ((System.nanoTime() - startTime) / 1000000) + "ms");
return c;
} catch (Exception e) {
Log.error("Failed to create dynamic class " + extend.getName() + " " + Arrays.toString(inherit));
throw new CubesException("Failed to make dynamic class", e);
}
}
private void fillDep(Grid grid) {
final int nbrCols = grid.getCols();
final int nbrRows = grid.getRows();
// flag for each grid cell to indicate whether it has been treated
BitSet closed = new BitSet(nbrCols * nbrRows);
// count the number of processed cells for the progress indicator
int nbrCellsProcessed = 0;
// plain queue
final int expectedMaxPlainSize = grid.getCols();
ArrayDeque<Cell> pit = new ArrayDeque(expectedMaxPlainSize);
// priority queue with cells ordered by elevation. Lowest elevation is
// the head of the queue.
PriorityQueue<Cell> open = new PriorityQueue(nbrCols * 2 + nbrRows * 2);
// add edge cells and void cells to priority queue
for (int row = 0; row < nbrRows && reportProgress(0); row++) {
for (int col = 0; col < nbrCols; col++) {
if (grid.isVoid(col, row)) {
continue;
}
if (isCellOnGridBorder(grid, col, row)) {
closed.set(col + row * nbrCols);
open.add(new Cell(col, row, grid.getValue(col, row)));
}
}
}
while (!open.isEmpty() || !pit.isEmpty()) {
// either consider the point with the lowest elevation in the queue
// or consider a point in/near a "pit" which is being filled
final Cell c = !pit.isEmpty() ? pit.pop() : open.poll();
++nbrCellsProcessed;
// look at neighbours of c
for (int i = 1; i <= 8; i++) {
final int nRow = c.row + DY[i];
final int nCol = c.col + DX[i];
// ensure neighbour is within the bounds of the grid
if (nRow < 0 || nCol < 0 || nRow >= nbrRows || nCol >= nbrCols) {
continue;
}
// ensure we haven't visited the cell yet
if (closed.get(nCol + nbrCols * nRow)) {
continue;
}
closed.set(nCol + nbrCols * nRow);
final float n = grid.getValue(nCol, nRow);
// ensure the cell is valid
if (Float.isNaN(n)) {
continue;
}
// if the current elevation is greater than the neighbour
// we are entering a depression therefore we add to the
// plain queue otherwise, add to the open queue
if (n <= c.elevation) {
if (n < c.elevation) {
// found a cell in a pit
grid.setValue(c.elevation, nCol, nRow);
}
pit.push(new Cell(nCol, nRow, c.elevation));
} else {
open.add(new Cell(nCol, nRow, n));
}
}
if (nbrCellsProcessed % 50000 == 0) {
if (!reportProgress(100f * nbrCellsProcessed / (nbrCols * nbrRows))) {
return;
}
}
}
}
/**
* Perform a depth first search of all states, starting at the start states
* <P>
* To avoid stack overflow errors on large DFAs, the implementation uses an auxiliary
* stack on the heap instead of recursing
*
* @param onEnter called with (parent, child) when a child is entered. parent == null for roots.
* @param onSkip called with (parent, child) when a child is skipped because it has been entered
* previously. parent == null for roots.
* @param onLeave called with (parent, child) when a child is exited. parent == null for roots.
*/
public void depthFirstSearch(
BiConsumer<DfaState<MATCHRESULT>, DfaState<MATCHRESULT>> onEnter,
BiConsumer<DfaState<MATCHRESULT>, DfaState<MATCHRESULT>> onSkip,
BiConsumer<DfaState<MATCHRESULT>, DfaState<MATCHRESULT>> onLeave)
{
@SuppressWarnings("unchecked")
final Iterator<DfaState<MATCHRESULT>>[] iterators =
(Iterator<DfaState<MATCHRESULT>>[]) new Iterator<?>[getStatesByNumber().size()];
final ArrayDeque<DfaState<MATCHRESULT>> stack = new ArrayDeque<>();
for (int rootIndex = 0; rootIndex < m_startStates.size(); ++rootIndex)
{
DfaState<MATCHRESULT> st = m_startStates.get(rootIndex);
if (iterators[st.getStateNumber()] != null)
{
onSkip.accept(null, st);
continue;
}
iterators[st.getStateNumber()] = st.getSuccessorStates().iterator();
stack.push(st);
onEnter.accept(null, st);
for (;;)
{
//process the next child of the stack top
st = stack.peek();
final int sti = st.getStateNumber();
final Iterator<DfaState<MATCHRESULT>> iter = iterators[sti];
if (iter.hasNext())
{
final DfaState<MATCHRESULT> child = iter.next();
if (child == null)
{
//shouldn't happen, but if it does get the next child
continue;
}
final int childi = child.getStateNumber();
if (iterators[childi] != null)
{
onSkip.accept(st, child);
}
else
{
iterators[childi] = child.getSuccessorStates().iterator();
stack.push(child);
onEnter.accept(st, child);
}
}
else
{
//top element is done
stack.pop();
if (stack.isEmpty())
{
onLeave.accept(null, st);
break;
}
onLeave.accept(stack.peek(), st);
}
}
}
}
<T> Optional<Pair<Falsification<T>, PrecursorDataPair<T>>> findFalsifyingValue(
Property<T> prop, LongSupplier clock) {
Guidance guidance = config.guidance();
Distribution<T> randomDistribution = new BoundarySkewedDistribution<>(config, prop.getGen());
ArrayDeque<long[]> toVisit = new ArrayDeque<>();
Distribution<T> distribution;
long endTime = clock.getAsLong() + config.testingTimeMillis();
for (int i = 0; i != config.examples(); i++) {
if (toVisit.isEmpty()) {
distribution = randomDistribution;
} else {
distribution = new ForcedDistribution<>(config, prop.getGen(), toVisit.pop());
}
PrecursorDataPair<T> t = distribution.generate();
if (checkHash(t)) {
continue;
}
examplesUsed = examplesUsed + 1;
guidance.newExample(t.precursor());
Optional<Falsification<T>> falsification = prop.tryFalsification(t.value());
guidance.exampleExecuted();
if (falsification.isPresent()) {
return falsification.map(f -> Pair.of(f, t));
} else {
toVisit.addAll(guidance.suggestValues(i,t.precursor()));
}
guidance.exampleComplete();
if (config.testingTimeMillis() > 0 && clock.getAsLong() > endTime) {
break;
}
}
return Optional.empty();
}