001/* 002 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.graph; 024 025import java.util.*; 026 027class TypedGraphNodeIterator<T extends IterableNodeType> implements Iterator<T> { 028 029 private final Graph graph; 030 private final int[] ids; 031 private final Node[] current; 032 033 private int currentIdIndex; 034 private boolean needsForward; 035 036 public TypedGraphNodeIterator(NodeClass<?> clazz, Graph graph) { 037 this.graph = graph; 038 ids = clazz.iterableIds(); 039 currentIdIndex = 0; 040 current = new Node[ids.length]; 041 Arrays.fill(current, Graph.PLACE_HOLDER); 042 needsForward = true; 043 } 044 045 private Node findNext() { 046 if (needsForward) { 047 forward(); 048 } else { 049 Node c = current(); 050 Node afterDeleted = graph.getIterableNodeNext(c); 051 if (afterDeleted == null) { 052 needsForward = true; 053 } else if (c != afterDeleted) { 054 setCurrent(afterDeleted); 055 } 056 } 057 if (needsForward) { 058 return null; 059 } 060 return current(); 061 } 062 063 private void forward() { 064 needsForward = false; 065 int startIdx = currentIdIndex; 066 while (true) { 067 Node next; 068 if (current() == Graph.PLACE_HOLDER) { 069 next = graph.getIterableNodeStart(ids[currentIdIndex]); 070 } else { 071 next = graph.getIterableNodeNext(current().typeCacheNext); 072 } 073 if (next == null) { 074 currentIdIndex++; 075 if (currentIdIndex >= ids.length) { 076 currentIdIndex = 0; 077 } 078 if (currentIdIndex == startIdx) { 079 needsForward = true; 080 return; 081 } 082 } else { 083 setCurrent(next); 084 break; 085 } 086 } 087 } 088 089 private Node current() { 090 return current[currentIdIndex]; 091 } 092 093 private void setCurrent(Node n) { 094 current[currentIdIndex] = n; 095 } 096 097 @Override 098 public boolean hasNext() { 099 return findNext() != null; 100 } 101 102 @Override 103 @SuppressWarnings("unchecked") 104 public T next() { 105 Node result = findNext(); 106 if (result == null) { 107 throw new NoSuchElementException(); 108 } 109 needsForward = true; 110 return (T) result; 111 } 112 113 @Override 114 public void remove() { 115 throw new UnsupportedOperationException(); 116 } 117}