Package org.xtreemfs.babudb.index.reader

Source Code of org.xtreemfs.babudb.index.reader.DiskIndexIteratorBase

/*
* Copyright (c) 2010, Jan Stender, Bjoern Kolbeck, Mikael Hoegqvist,
*                     Felix Hupfeld, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/

package org.xtreemfs.babudb.index.reader;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.FileChannel;
import java.util.Iterator;
import java.util.Map.Entry;

import org.xtreemfs.babudb.index.ByteRange;
import org.xtreemfs.foundation.logging.Logging;

public abstract class DiskIndexIteratorBase {
   
    private final DiskIndex                         index;
   
    private final byte[]                            from;
   
    private final byte[]                            to;
   
    private final BlockReader                       blockIndexReader;
   
    private final ByteBuffer[]                      maps;
   
    private final FileChannel[]                     dbFileChannels;
   
    private final int                               blockIndexStart;
   
    private final int                               blockIndexEnd;
   
    private final boolean                           ascending;
   
    private int                                     currentBlockIndex;
   
    private BlockReader                             currentBlock;
   
    protected Iterator<Entry<ByteRange, ByteRange>> currentBlockIterator;
   
    protected DiskIndexIteratorBase(DiskIndex index, BlockReader blockIndexReader, byte[] from, byte[] to,
        boolean ascending, ByteBuffer[] maps, FileChannel[] dbFileChannels) {
       
        this.maps = maps;
        this.dbFileChannels = dbFileChannels;
        this.index = index;
        this.from = from;
        this.to = to;
        this.ascending = ascending;
       
        this.blockIndexReader = blockIndexReader.clone();
       
        // determine the first potential block containing entries with keys in
        // the range
        int tmp = from == null ? 0 : index.getBlockIndexPosition(from, blockIndexReader);
        if (tmp < 0)
            tmp = 0;
        this.blockIndexStart = tmp;
       
        // determine the last potential block containing entries with keys in
        // the range
        tmp = to == null ? blockIndexReader.getNumEntries() - 1 : index.getBlockIndexPosition(to,
            blockIndexReader);
        if (tmp > blockIndexReader.getNumEntries() - 1)
            tmp = blockIndexReader.getNumEntries() - 1;
        this.blockIndexEnd = tmp;
       
        currentBlockIndex = ascending ? blockIndexStart : blockIndexEnd;
        getNextBlockData();
    }
   
    public boolean hasNext() {
       
        while (currentBlockIterator != null) {
           
            if (currentBlockIterator.hasNext())
                return true;
           
            if (ascending)
                currentBlockIndex++;
            else
                currentBlockIndex--;
           
            getNextBlockData();
        }
       
        return false;
    }
   
    public void remove() {
        throw new UnsupportedOperationException();
    }
   
    public void free() {
        // also check if the buffer has been returned already; this may happen
        // if all elements have been accessed before
        if (currentBlock != null && currentBlock.readBuffer != null
            && currentBlock.readBuffer.getRefCount() > 0)
            currentBlock.free();
    }
   
    protected void finalize() throws Throwable {
        free();
        super.finalize();
    }
   
    private void getNextBlockData() {
       
        if (blockIndexStart == -1 && blockIndexEnd == -1)
            return;
       
        // ascending
        if (ascending && currentBlockIndex > blockIndexEnd) {
            currentBlock = null;
            currentBlockIterator = null;
            return;
        }

        // descending
        else if (!ascending && currentBlockIndex < blockIndexStart) {
            currentBlock = null;
            currentBlockIterator = null;
            return;
        }
       
        int startOffset = DiskIndex.getBlockOffset(currentBlockIndex, blockIndexReader);
        // when last block or a single block the offset should be the
        // size of the block
       
        int fileId = DiskIndex.getBlockFileId(currentBlockIndex, blockIndexReader);
        int endOffset;
        if (currentBlockIndex == blockIndexReader.getNumEntries() - 1)
            // the last block in the block index
            endOffset = -1;
        else {
            ByteRange indexPos = DiskIndex.getBlockEntry(currentBlockIndex + 1, blockIndexReader);
            ByteBuffer indexPosBuf = indexPos.getBuf();
            endOffset = DiskIndex.getBlockIndexOffset(indexPosBuf, indexPos.getStartOffset());
           
            // is this the last block of the current block file?
            // then the endBlockOffset should be set to the end of the
            // file
            if (DiskIndex.getBlockIndexFileId(indexPosBuf, indexPos.getStartOffset()) > fileId)
                endOffset = -1;
           
            // endBlockOffset = getBlockOffset(indexPosition + 1,
            // blockIndex);
        }
       
        try {
            currentBlock = maps != null ? index.getBlock(startOffset, endOffset, maps[fileId]) : index
                    .getBlock(startOffset, endOffset, dbFileChannels[fileId]);
        } catch (ClosedByInterruptException exc) {
            Logging.logError(Logging.LEVEL_DEBUG, this, exc);
        } catch (IOException exc) {
            Logging.logError(Logging.LEVEL_ERROR, this, exc);
        }
       
        currentBlockIterator = currentBlock == null ? null : currentBlock.rangeLookup(from == null ? null
            : from, to == null ? null : to, ascending);
    }
   
}
TOP

Related Classes of org.xtreemfs.babudb.index.reader.DiskIndexIteratorBase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.