Package com.foundationdb.qp.storeadapter

Source Code of com.foundationdb.qp.storeadapter.FDBAdapter

/**
* Copyright (C) 2009-2013 FoundationDB, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.foundationdb.qp.storeadapter;

import com.foundationdb.ais.model.Group;
import com.foundationdb.ais.model.GroupIndex;
import com.foundationdb.ais.model.Index;
import com.foundationdb.ais.model.Sequence;
import com.foundationdb.ais.model.TableIndex;
import com.foundationdb.qp.expression.IndexKeyRange;
import com.foundationdb.qp.operator.API;
import com.foundationdb.qp.operator.IndexScanSelector;
import com.foundationdb.qp.operator.QueryBindings;
import com.foundationdb.qp.operator.QueryContext;
import com.foundationdb.qp.operator.RowCursor;
import com.foundationdb.qp.operator.StoreAdapter;
import com.foundationdb.qp.storeadapter.indexcursor.IterationHelper;
import com.foundationdb.qp.storeadapter.indexcursor.MergeJoinSorter;
import com.foundationdb.qp.storeadapter.indexrow.IndexRowPool;
import com.foundationdb.qp.storeadapter.indexrow.FDBIndexRow;
import com.foundationdb.qp.row.HKey;
import com.foundationdb.qp.row.IndexRow;
import com.foundationdb.qp.row.Row;
import com.foundationdb.qp.row.ValuesHKey;
import com.foundationdb.qp.rowtype.IndexRowType;
import com.foundationdb.qp.rowtype.RowType;
import com.foundationdb.qp.rowtype.Schema;
import com.foundationdb.server.error.AkibanInternalException;
import com.foundationdb.server.error.DuplicateKeyException;
import com.foundationdb.server.error.FDBAdapterException;
import com.foundationdb.server.error.FDBCommitUnknownResultException;
import com.foundationdb.server.error.FDBFutureVersionException;
import com.foundationdb.server.error.FDBNotCommittedException;
import com.foundationdb.server.error.FDBPastVersionException;
import com.foundationdb.server.error.InvalidOperationException;
import com.foundationdb.server.error.QueryCanceledException;
import com.foundationdb.server.rowdata.RowData;
import com.foundationdb.server.rowdata.RowDef;
import com.foundationdb.server.service.config.ConfigurationService;
import com.foundationdb.server.service.session.Session;
import com.foundationdb.server.store.FDBStore;
import com.foundationdb.server.store.FDBTransactionService;
import com.foundationdb.util.tap.InOutTap;
import com.foundationdb.FDBException;
import com.persistit.Key;

import java.io.InterruptedIOException;
import java.util.Collection;

public class FDBAdapter extends StoreAdapter {
    private static final IndexRowPool indexRowPool = new IndexRowPool();

    private final FDBStore store;
    private final FDBTransactionService txnService;

    public FDBAdapter(FDBStore store, Schema schema, Session session, FDBTransactionService txnService, ConfigurationService config) {
        super(schema, session, config);
        this.store = store;
        this.txnService = txnService;
    }

    @Override
    public FDBGroupCursor newGroupCursor(Group group) {
        return new FDBGroupCursor(this, group);
    }

    @Override
    public FDBGroupCursor newDumpGroupCursor(Group group, int commitFrequency) {
        return new FDBGroupCursor(this, group, commitFrequency);
    }

    @Override
    public RowCursor newIndexCursor(QueryContext context,
                                    Index index,
                                    IndexKeyRange keyRange,
                                    API.Ordering ordering,
                                    IndexScanSelector scanSelector,
                                    boolean openAllSubCursors) {
        return new PersistitIndexCursor(context,
                                        schema.indexRowType(index),
                                        keyRange,
                                        ordering,
                                        scanSelector,
                                        openAllSubCursors);
    }

    @Override
    public HKey newHKey(com.foundationdb.ais.model.HKey hKeyMetadata) {
        return new ValuesHKey(schema.newHKeyRowType(hKeyMetadata), store.getTypesRegistry());
    }

    @Override
    public void updateRow(Row oldRow, Row newRow) {
        RowDef rowDef = oldRow.rowType().table().rowDef();
        RowDef rowDefNewRow = newRow.rowType().table().rowDef();
        if (rowDef.getRowDefId() != rowDefNewRow.getRowDefId()) {
            throw new IllegalArgumentException(String.format("%s != %s", rowDef, rowDefNewRow));
        }
        RowData oldRowData = rowData(rowDef, oldRow, new RowDataCreator());
        RowData newRowData = rowData(rowDefNewRow, newRow, new RowDataCreator());
        try {
            store.updateRow(getSession(), rowDef, oldRowData, rowDefNewRow, newRowData, null);
        } catch(InvalidOperationException e) {
            rollbackIfNeeded(getSession(), e);
            throw e;
        }
    }

    @Override
    public void writeRow(Row newRow, Collection<TableIndex> indexes, Collection<GroupIndex> groupIndexes) {
        RowDef rowDef = newRow.rowType().table().rowDef();
        RowData newRowData = rowData(rowDef, newRow, new RowDataCreator());
        try {
            store.writeRow(getSession(), rowDef, newRowData, indexes, groupIndexes);
        } catch(InvalidOperationException e) {
            rollbackIfNeeded(getSession(), e);
            throw e;
        }
    }

    @Override
    public void deleteRow(Row oldRow, boolean cascadeDelete) {
        RowDef rowDef = oldRow.rowType().table().rowDef();
        RowData oldRowData = rowData(rowDef, oldRow, new RowDataCreator());
        try {
            store.deleteRow(getSession(), rowDef, oldRowData, cascadeDelete);
        } catch(InvalidOperationException e) {
            rollbackIfNeeded(getSession(), e);
            throw e;
        }
    }

    @Override
    public Sorter createSorter(QueryContext context,
                               QueryBindings bindings,
                               RowCursor input,
                               RowType rowType,
                               API.Ordering ordering,
                               API.SortOption sortOption,
                               InOutTap loadTap) {
        return new MergeJoinSorter(context, bindings, input, rowType, ordering, sortOption, loadTap);
    }

    @Override
    public long sequenceNextValue(Sequence sequence) {
        return store.nextSequenceValue(getSession(), sequence);
    }

    @Override
    public long sequenceCurrentValue(Sequence sequence) {
        return store.curSequenceValue(getSession(), sequence);
    }

    @Override
    public IndexRow newIndexRow(IndexRowType indexRowType)
    {
        return new FDBIndexRow (this, indexRowType);
    }
   
    @Override
    public IndexRow takeIndexRow(IndexRowType indexRowType)
    {
        return indexRowPool.takeIndexRow(this, indexRowType);
    }

    @Override
    public void returnIndexRow(IndexRow indexRow)
    {
        indexRowPool.returnIndexRow(this, indexRow.rowType(), indexRow);
    }

    @Override
    public IterationHelper createIterationHelper(IndexRowType indexRowType) {
        return new FDBIterationHelper(this, indexRowType);
    }

    @Override
    protected FDBStore getUnderlyingStore() {
        return store;
    }

    @Override
    public Key createKey() {
        return store.createKey();
    }


    public FDBTransactionService.TransactionState getTransaction() {
        return txnService.getTransaction(getSession());
    }

    //
    // Internal
    //

    public static boolean isFromInterruption(Exception e) {
        Throwable c = e.getCause();
        // TODO: Is the IO needed?
        return (e instanceof InterruptedException) || (e instanceof InterruptedIOException) ||
               (c instanceof InterruptedException) || (c instanceof InterruptedIOException);
    }

    public static RuntimeException wrapFDBException(Session session, Exception e)
    {
        if (isFromInterruption(e)) {
            return new QueryCanceledException(session);
        } else if (e instanceof FDBException) {
            FDBException fdbEx = (FDBException)e;
            switch (fdbEx.getCode()) {
            case 1007:          // past_version
                return new FDBPastVersionException(fdbEx);
            case 1009:          // future_version
                return new FDBFutureVersionException(fdbEx);
            case 1020:          // not_committed
                return new FDBNotCommittedException(fdbEx);
            case 1021:          // commit_unknown_result
                return new FDBCommitUnknownResultException(fdbEx);
            default:
                return new FDBAdapterException(fdbEx);
            }
        } else if (e instanceof RuntimeException) {
            return (RuntimeException)e;
        } else {
            return new AkibanInternalException("unexpected error from data layer", e);
        }
    }

    private void rollbackIfNeeded(Session session, Exception e) {
        if((e instanceof DuplicateKeyException) || (e instanceof FDBException) || isFromInterruption(e)) {
            store.setRollbackPending(session);
        }
    }
}
TOP

Related Classes of com.foundationdb.qp.storeadapter.FDBAdapter

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.