Package org.xtreemfs.babudb.snapshots

Source Code of org.xtreemfs.babudb.snapshots.InMemoryView

/*
* Copyright (c) 2009 - 2011, Jan Stender, Bjoern Kolbeck, Mikael Hoegqvist,
*                     Felix Hupfeld, Felix Langner, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.babudb.snapshots;

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

import org.xtreemfs.babudb.api.database.ResultSet;
import org.xtreemfs.babudb.api.dev.BabuDBInternal;
import org.xtreemfs.babudb.api.dev.DatabaseInternal;
import org.xtreemfs.babudb.api.exception.BabuDBException;
import org.xtreemfs.babudb.api.exception.BabuDBException.ErrorCode;

/**
* This class provides simple read-only access to all immutable on-disk indices
* of a BabuDB database.
*
* @author stender
*
*/
public class InMemoryView implements BabuDBView {
   
    private DatabaseInternal      db;
   
    private Map<Integer, Integer> snapIDMap;
   
    private SnapshotConfig        snap;
   
    public InMemoryView(BabuDBInternal babuDB, String dbName, SnapshotConfig snap, int[] snapIDs)
        throws BabuDBException {
       
        this.db = babuDB.getDatabaseManager().getDatabase(dbName);
        this.snap = snap;
       
        snapIDMap = new HashMap<Integer, Integer>();
        for (int i = 0; i < snap.getIndices().length; i++)
            snapIDMap.put(snap.getIndices()[i], snapIDs[i]);
       
    }
   
    @Override
    public byte[] directLookup(int indexId, byte[] key) throws BabuDBException {
       
        Integer snapId = snapIDMap.get(indexId);
        if (snapId == null)
            throw new BabuDBException(ErrorCode.NO_SUCH_INDEX, "index " + indexId + " does not exist");
       
        return (isCovered(indexId, key) && snap.containsKey(indexId, key)) ?
                db.directLookup(indexId, snapId, key) : null;
    }
   
    @Override
    public ResultSet<byte[], byte[]> directPrefixLookup(final int indexId, final byte[] key,
        final boolean ascending) throws BabuDBException {
       
        final Integer snapId = snapIDMap.get(indexId);
        if (snapId == null)
            throw new BabuDBException(ErrorCode.NO_SUCH_INDEX, "index " + indexId + " does not exist");
       
        return new ResultSet<byte[], byte[]>() {
           
            private ResultSet<byte[], byte[]> it;
           
            private Entry<byte[], byte[]>           next;
           
            {
                it = db.directPrefixLookup(indexId, snapId, key, ascending);
                getNextEntry();
            }
           
            @Override
            public boolean hasNext() {
                return next != null;
            }
           
            @Override
            public Entry<byte[], byte[]> next() {
               
                if (next == null)
                    throw new NoSuchElementException();
               
                Entry<byte[], byte[]> tmp = next;
                getNextEntry();
               
                return tmp;
            }
           
            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
           
            private void getNextEntry() {
               
                while (it.hasNext()) {
                    next = it.next();
                    if (isCovered(indexId, next.getKey()) && snap.containsKey(indexId, next.getKey()))
                        return;
                }
               
                next = null;
            }

            @Override
            public void free() {
                it.free();
            }
        };
    }
   
    @Override
    public ResultSet<byte[], byte[]> directRangeLookup(final int indexId, final byte[] from,
        final byte[] to, final boolean ascending) throws BabuDBException {
       
        final Integer snapId = snapIDMap.get(indexId);
        if (snapId == null)
            throw new BabuDBException(ErrorCode.NO_SUCH_INDEX, "index " + indexId + " does not exist");
       
        return new ResultSet<byte[], byte[]>() {
           
            private ResultSet<byte[], byte[]> it;
           
            private Entry<byte[], byte[]>           next;
           
            {
                it = db.directRangeLookup(indexId, snapId, from, to, ascending);
                getNextEntry();
            }
           
            @Override
            public boolean hasNext() {
                return next != null;
            }
           
            @Override
            public Entry<byte[], byte[]> next() {
               
                if (next == null)
                    throw new NoSuchElementException();
               
                Entry<byte[], byte[]> tmp = next;
                getNextEntry();
               
                return tmp;
            }
           
            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
           
            private void getNextEntry() {
               
                while (it.hasNext()) {
                    next = it.next();
                    if (isCovered(indexId, next.getKey()) && snap.containsKey(indexId, next.getKey()))
                        return;
                }
               
                next = null;
            }

            @Override
            public void free() {
                it.free();
            }
           
        };
    }
   
    @Override
    public void shutdown() throws BabuDBException {
        // nothing to do
    }
   
    private boolean isCovered(int index, byte[] key) {
       
        if (snap.getPrefixes(index) == null)
            return true;
       
        for (byte[] prefix : snap.getPrefixes(index))
            if (startsWith(key, prefix))
                return true;
       
        return false;
    }
   
    private static boolean startsWith(byte[] key, byte[] prefix) {
       
        if (key.length >= prefix.length) {
           
            for (int i = 0; i < prefix.length; i++)
                if (key[i] != prefix[i])
                    return false;
           
            return true;
        }
       
        return false;
    }
   
}
TOP

Related Classes of org.xtreemfs.babudb.snapshots.InMemoryView

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.