Mercurial > hg > truffle
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 } |