comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @ 16468:9fa5872291c1

Truffle: improve NodeIterator
author Andreas Woess <andreas.woess@jku.at>
date Thu, 10 Jul 2014 18:15:29 +0200
parents 17f7331dcc4f
children d86f948268da
comparison
equal deleted inserted replaced
16467:17f7331dcc4f 16468:9fa5872291c1
250 return new NodeIterator(node); 250 return new NodeIterator(node);
251 } 251 }
252 252
253 private final class NodeIterator implements Iterator<Node> { 253 private final class NodeIterator implements Iterator<Node> {
254 private final Node node; 254 private final Node node;
255 private final int childrenCount; 255 private int fieldIndex;
256 private int index; 256 private int arrayIndex;
257 257
258 protected NodeIterator(Node node) { 258 protected NodeIterator(Node node) {
259 this.node = node; 259 this.node = node;
260 this.index = 0; 260 }
261 this.childrenCount = childrenCount(); 261
262 } 262 private void forward() {
263 263 if (fieldIndex < childOffsets.length) {
264 private int childrenCount() { 264 fieldIndex++;
265 int nodeCount = childOffsets.length; 265 } else if (fieldIndex < childOffsets.length + childrenOffsets.length) {
266 for (long fieldOffset : childrenOffsets) { 266 if (arrayIndex + 1 < currentChildrenArrayLength()) {
267 Node[] children = ((Node[]) unsafe.getObject(node, fieldOffset)); 267 arrayIndex++;
268 if (children != null) { 268 } else {
269 nodeCount += children.length; 269 arrayIndex = 0;
270 do {
271 fieldIndex++;
272 } while (fieldIndex < childOffsets.length + childrenOffsets.length && currentChildrenArrayLength() == 0);
270 } 273 }
271 } 274 }
272 return nodeCount; 275 }
273 } 276
274 277 public boolean hasNext() {
275 private Node nodeAt(int idx) { 278 return fieldIndex < childOffsets.length || (fieldIndex < childOffsets.length + childrenOffsets.length && arrayIndex < currentChildrenArrayLength());
276 int nodeCount = childOffsets.length; 279 }
277 if (idx < nodeCount) { 280
278 return (Node) unsafe.getObject(node, childOffsets[idx]); 281 private Node[] currentChildrenArray() {
282 assert fieldIndex >= childOffsets.length && fieldIndex < childOffsets.length + childrenOffsets.length;
283 return (Node[]) unsafe.getObject(node, childrenOffsets[fieldIndex - childOffsets.length]);
284 }
285
286 private int currentChildrenArrayLength() {
287 Node[] childrenArray = currentChildrenArray();
288 return childrenArray != null ? childrenArray.length : 0;
289 }
290
291 public Node next() {
292 Node next;
293 if (fieldIndex < childOffsets.length) {
294 next = (Node) unsafe.getObject(node, childOffsets[fieldIndex]);
295 } else if (fieldIndex < childOffsets.length + childrenOffsets.length) {
296 next = currentChildrenArray()[arrayIndex];
279 } else { 297 } else {
280 for (long fieldOffset : childrenOffsets) { 298 throw new NoSuchElementException();
281 Node[] nodeArray = (Node[]) unsafe.getObject(node, fieldOffset); 299 }
282 if (idx < nodeCount + nodeArray.length) { 300 forward();
283 return nodeArray[idx - nodeCount]; 301 return next;
284 }
285 nodeCount += nodeArray.length;
286 }
287 }
288 return null;
289 }
290
291 private void forward() {
292 if (index < childrenCount) {
293 index++;
294 }
295 }
296
297 public boolean hasNext() {
298 return index < childrenCount;
299 }
300
301 public Node next() {
302 try {
303 return nodeAt(index);
304 } finally {
305 forward();
306 }
307 } 302 }
308 303
309 public void remove() { 304 public void remove() {
310 throw new UnsupportedOperationException(); 305 throw new UnsupportedOperationException();
311 } 306 }