public final Iterator iterator()

in utils/src/main/java/jetbrains/exodus/core/dataStructures/persistent/AbstractPersistent23Tree.java [70:138]


    public final Iterator<K> iterator() {
        final RootNode<K> root = getRoot();
        if (root == null) {
            return Collections.EMPTY_LIST.iterator();
        }
        final TreePos<K>[] stack = new TreePos[MathUtil.integerLogarithm(root.getSize()) + 1];
        for (int i = 0; i < stack.length; ++i) {
            stack[i] = new TreePos<>(root);
        }
        return new Iterator<K>() {

            private int i = 0;
            private boolean hasNext;
            private boolean hasNextValid;

            @Override
            public boolean hasNext() {
                if (hasNextValid) {
                    return hasNext;
                }
                hasNextValid = true;
                TreePos<K> treePos = stack[i];
                if (treePos.node.isLeaf()) {
                    while (treePos.pos >= (treePos.node.isTernary() ? 2 : 1)) {
                        if (--i < 0) {
                            hasNext = false;
                            return false;
                        }
                        treePos = stack[i];
                    }
                } else {
                    TreePos<K> newPos = stack[++i];
                    newPos.pos = 0;
                    if (treePos.pos == 0) {
                        newPos.node = treePos.node.getFirstChild();
                    } else if (treePos.pos == 1) {
                        newPos.node = treePos.node.getSecondChild();
                    } else {
                        newPos.node = treePos.node.getThirdChild();
                    }
                    treePos = newPos;
                    while (!treePos.node.isLeaf()) {
                        newPos = stack[++i];
                        newPos.pos = 0;
                        newPos.node = treePos.node.getFirstChild();
                        treePos = newPos;
                    }
                }
                treePos.pos++;
                return hasNext = true;
            }

            @Override
            public K next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                hasNextValid = false;
                final TreePos<K> treePos = stack[i];
                // treePos.pos must be 1 or 2 here
                return treePos.pos == 1 ? treePos.node.getFirstKey() : treePos.node.getSecondKey();
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }