All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tech.pantheon.triemap.AbstractIterator Maven / Gradle / Ivy

Go to download

Java implementation of a concurrent trie hash map from Scala collections library

There is a newer version: 1.3.2
Show newest version
/*
 * (C) Copyright 2017 Pantheon Technologies, s.r.o. and others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package tech.pantheon.triemap;

import static tech.pantheon.triemap.Constants.MAX_DEPTH;

import java.util.Iterator;
import java.util.Map.Entry;
import java.util.NoSuchElementException;

/**
 * Abstract base class for iterators supporting {@link AbstractEntrySet} subclasses.
 *
 * @author Robert Varga
 *
 * @param  the type of entry keys
 * @param  the type of entry values
 */
abstract class AbstractIterator implements Iterator> {
    private final BasicNode[][] nodeStack = new BasicNode[MAX_DEPTH][];
    private final int[] positionStack = new int[MAX_DEPTH];
    private final TrieMap map;

    private LNodeEntries lnode;
    private EntryNode current;
    private int depth = -1;

    AbstractIterator(final ImmutableTrieMap map) {
        this.map = map;
        readin(map.readRoot());
    }

    @Override
    public final boolean hasNext() {
        return current != null || lnode != null;
    }

    @Override
    public final Entry next() {
        final Entry entry;

        // Check LNode iterator first
        if (lnode != null) {
            entry = lnode;
            lnode = lnode.next();
            if (lnode == null) {
                advance();
            }
        } else {
            entry = current;
            advance();
        }

        if (entry == null) {
            throw new NoSuchElementException();
        }

        return wrapEntry(entry);
    }

    /**
     * Wrap entry so it can be presented to the user.
     *
     * @param entry An immutable entry, guaranteed to be non-null
     * @return Wrapped entry, may not be null
     */
    abstract Entry wrapEntry(Entry entry);

    /**
     * Read the contents of an INode's main node.
     *
     * @param in INode to be read.
     */
    private void readin(final INode in) {
        final MainNode m = in.gcasRead(map);
        if (m instanceof CNode) {
            // Enter the next level
            final CNode cn = (CNode) m;
            depth++;
            nodeStack[depth] = cn.array;
            positionStack[depth] = -1;
            advance();
        } else if (m instanceof TNode) {
            current = (TNode) m;
        } else if (m instanceof LNode) {
            lnode = ((LNode) m).entries();
        } else if (m == null) {
            current = null;
        }
    }

    @SuppressWarnings("unchecked")
    private void advance() {
        if (depth >= 0) {
            int npos = positionStack[depth] + 1;
            if (npos < nodeStack[depth].length) {
                positionStack [depth] = npos;
                BasicNode elem = nodeStack[depth][npos];
                if (elem instanceof SNode) {
                    current = (SNode) elem;
                } else if (elem instanceof INode) {
                    readin((INode) elem);
                }
            } else {
                depth -= 1;
                advance();
            }
        } else {
            current = null;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy