comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @ 16581:8be5c68a779d

Truffle: revert to previous iterator implementation, add test case
author Andreas Woess <andreas.woess@jku.at>
date Tue, 22 Jul 2014 16:32:43 +0200
parents a3b0a2d61e62
children 70f47dbbcabd
comparison
equal deleted inserted replaced
16580:a7d9b88ecd68 16581:8be5c68a779d
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 int fieldIndex; 255 private final int childrenCount;
256 private int arrayIndex; 256 private int index;
257 257
258 protected NodeIterator(Node node) { 258 protected NodeIterator(Node node) {
259 this.node = node; 259 this.node = node;
260 this.index = 0;
261 this.childrenCount = childrenCount();
262 }
263
264 private int childrenCount() {
265 int nodeCount = childOffsets.length;
266 for (long fieldOffset : childrenOffsets) {
267 Node[] children = ((Node[]) unsafe.getObject(node, fieldOffset));
268 if (children != null) {
269 nodeCount += children.length;
270 }
271 }
272 return nodeCount;
273 }
274
275 private Node nodeAt(int idx) {
276 int nodeCount = childOffsets.length;
277 if (idx < nodeCount) {
278 return (Node) unsafe.getObject(node, childOffsets[idx]);
279 } else {
280 for (long fieldOffset : childrenOffsets) {
281 Node[] nodeArray = (Node[]) unsafe.getObject(node, fieldOffset);
282 if (idx < nodeCount + nodeArray.length) {
283 return nodeArray[idx - nodeCount];
284 }
285 nodeCount += nodeArray.length;
286 }
287 }
288 return null;
260 } 289 }
261 290
262 private void forward() { 291 private void forward() {
263 if (fieldIndex < childOffsets.length) { 292 if (index < childrenCount) {
264 fieldIndex++; 293 index++;
265 } else if (fieldIndex < childOffsets.length + childrenOffsets.length) {
266 if (arrayIndex + 1 < currentChildrenArrayLength()) {
267 arrayIndex++;
268 } else {
269 arrayIndex = 0;
270 do {
271 fieldIndex++;
272 } while (fieldIndex < childOffsets.length + childrenOffsets.length && currentChildrenArrayLength() == 0);
273 }
274 } 294 }
275 } 295 }
276 296
277 public boolean hasNext() { 297 public boolean hasNext() {
278 return fieldIndex < childOffsets.length || (fieldIndex < childOffsets.length + childrenOffsets.length && arrayIndex < currentChildrenArrayLength()); 298 return index < childrenCount;
279 }
280
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 } 299 }
290 300
291 public Node next() { 301 public Node next() {
292 Node next; 302 try {
293 if (fieldIndex < childOffsets.length) { 303 return nodeAt(index);
294 next = (Node) unsafe.getObject(node, childOffsets[fieldIndex]); 304 } finally {
295 } else if (fieldIndex < childOffsets.length + childrenOffsets.length) { 305 forward();
296 next = currentChildrenArray()[arrayIndex]; 306 }
297 } else {
298 throw new NoSuchElementException();
299 }
300 forward();
301 return next;
302 } 307 }
303 308
304 public void remove() { 309 public void remove() {
305 throw new UnsupportedOperationException(); 310 throw new UnsupportedOperationException();
306 } 311 }