public Iterator tailReverseIterator()

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


    public Iterator<K> tailReverseIterator(@NotNull final K key) {
        return new Iterator<K>() {

            private Stack<TreePosRev<K>> stack;
            private boolean hasNext;
            private boolean hasNextValid;
            private K bound;

            @Override
            public boolean hasNext() {
                if (hasNextValid) {
                    return hasNext;
                }
                hasNextValid = true;
                if (stack == null) {
                    Node<K> root = getRoot();
                    if (root == null) {
                        hasNext = false;
                        return false;
                    }
                    bound = getLess(root, key);
                    stack = new Stack<>();
                    stack.push(new TreePosRev<>(root));
                }
                TreePosRev<K> treePos = stack.peek();
                if (treePos.node.isLeaf()) {
                    while (treePos.pos <= 1) {
                        stack.pop();
                        if (stack.isEmpty()) {
                            hasNext = false;
                            return false;
                        }
                        treePos = stack.peek();
                    }
                } else {
                    if (treePos.pos == 1) {
                        treePos = new TreePosRev<>(treePos.node.getFirstChild());
                    } else if (treePos.pos == 2) {
                        treePos = new TreePosRev<>(treePos.node.getSecondChild());
                    } else {
                        treePos = new TreePosRev<>(treePos.node.getThirdChild());
                    }
                    stack.push(treePos);
                    while (!treePos.node.isLeaf()) {
                        treePos = new TreePosRev<>(treePos.node.isTernary() ? treePos.node.getThirdChild() : treePos.node.getSecondChild());
                        stack.push(treePos);
                    }
                }
                treePos.pos--;
                hasNext = tryNext() != bound;
                return hasNext;
            }

            @Override
            public K next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                hasNextValid = false;
                return tryNext();
            }

            private K tryNext() {
                TreePosRev<K> treePos = stack.peek();
                // 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();
            }
        };
    }