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

com.bigdata.btree.LeafTupleIterator Maven / Gradle / Ivy

/**

Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.

Contact:
     SYSTAP, LLC DBA Blazegraph
     2501 Calvert ST NW #106
     Washington, DC 20008
     [email protected]

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
/*
 * Created on Nov 15, 2006
 */
package com.bigdata.btree;

import java.util.NoSuchElementException;

/**
 * Visits the values of a {@link Leaf} in the external key ordering. There is
 * exactly one value per key for a leaf node.
 * 
 * @author Bryan Thompson
 * @version $Id$
 */
public class LeafTupleIterator implements ITupleIterator {

    private final Leaf leaf;

    private final AbstractTuple tuple;
    
    private int index;

    private int lastVisited = -1;

//    private final byte[] fromKey;
//    
//    private final byte[] toKey;

    // first index to visit.
    private final int fromIndex;

    // first index to NOT visit.
    private final int toIndex;

    private final boolean hasDeleteMarkers;
    
    private final boolean visitDeleted;
    
    public LeafTupleIterator(Leaf leaf) {

        this(leaf, new Tuple(leaf.btree, IRangeQuery.DEFAULT), null, null);

    }

    public LeafTupleIterator(final Leaf leaf, final AbstractTuple tuple) {

        this(leaf, tuple, null, null);

    }

    /**
     * 
     * @param leaf
     *            The leaf whose entries will be traversed (required).
     * @param tuple
     *            Used to hold the output values (required).
     * @param fromKey
     *            The first key whose entry will be visited or null
     *            if the lower bound on the key traversal is not constrained.
     * @param toKey
     *            The first key whose entry will NOT be visited or
     *            null if the upper bound on the key traversal is
     *            not constrained.
     * @param flags
     *            Flags specifying whether the keys and/or values will be
     *            materialized.
     * 
     * @exception IllegalArgumentException
     *                if fromKey is given and is greater than toKey.
     */
    public LeafTupleIterator(final Leaf leaf, final AbstractTuple tuple,
            final byte[] fromKey, final byte[] toKey) {

        assert leaf != null;

        assert tuple != null;

        this.leaf = leaf;
        
        this.tuple = tuple;

        this.hasDeleteMarkers = leaf.hasDeleteMarkers();

        this.visitDeleted = (tuple.flags() & IRangeQuery.DELETED) != 0;

//        this.fromKey = fromKey; // may be null (no lower bound).
//        
//        this.toKey = toKey; // may be null (no upper bound).
        
        { // figure out the first index to visit.

            int fromIndex;

            if (fromKey != null) {

                fromIndex = leaf.getKeys().search(fromKey);

                if (fromIndex < 0) {

                    fromIndex = -fromIndex - 1;

                }

            } else {

                fromIndex = 0;

            }

            this.fromIndex = fromIndex;

        }

        { // figure out the first index to NOT visit.

            int toIndex;

            if (toKey != null) {

                toIndex = leaf.getKeys().search(toKey);

                if (toIndex < 0) {

                    toIndex = -toIndex - 1;

                }

            } else {

                toIndex = leaf.getKeyCount();

            }

            this.toIndex = toIndex;

        }

        if (fromIndex > toIndex) {
            
            throw new IllegalArgumentException("fromKey > toKey");
            
        }
        
        // starting index is the lower bound.
        index = fromIndex;
        
    }

    /**
     * Examines the entry at {@link #index}. If it passes the criteria for an
     * entry to visit then return true. Otherwise increment the {@link #index}
     * until either all entries in this leaf have been exhausted -or- the an
     * entry is identified that passes the various criteria.
     */
    public boolean hasNext() {

//        if(filter == null) {
//            
//            return index >= fromIndex && index < toIndex;
//            
//        }

        for( ; index >= fromIndex && index < toIndex; index++) {
         
            /*
             * Skip deleted entries unless specifically requested.
             */
            if (hasDeleteMarkers && !visitDeleted
                    && leaf.getDeleteMarker(index)) {

                // skipping a deleted version.
                
                continue;
                
            }

            // entry @ index is next to visit.
            
            return true;
            
        }

        // nothing left to visit in this leaf.
        
        return false;
        
    }
    
    public ITuple next() {

        if (!hasNext()) {

            throw new NoSuchElementException();

        }

        lastVisited = index++;

        tuple.copy(lastVisited, leaf);
        
        return tuple;
        
    }

    /**
     * This operation is not supported.
     * 

* Note: There are two ways in which you can achieve the semantics of * {@link #remove()}. One is to use an {@link ITupleCursor}, which * correctly handles traversal with concurrent modification. The other is to * use a {@link AbstractChunkedTupleIterator}, which buffers the tuples * first and then does a "delete" behind in order to avoid concurrent * modification during traversal. * * @throws UnsupportedOperationException * always. */ public void remove() { throw new UnsupportedOperationException(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy