Search in sources :

Example 1 with SearchParameters

use of org.apache.derby.impl.store.access.btree.SearchParameters in project derby by apache.

the class B2IUndo method findUndo.

/**
 * Find the page and record to undo.  If no logical undo is necessary,
 * i.e., row has not moved, then just return the latched page where undo
 * should go.  If the record has moved, it has a new recordId on the new
 * page, this routine needs to call pageOp.resetRecord with the new
 * RecordHandle so that the logging system can update the compensation
 * Operation with the new location.
 *
 * @param rawtran   the transaction doing the rollback
 * @param pageOp    the page operation that supports logical undo.  This
 * 		            LogicalUndo function pointer is a field of that
 * 		            pageOperation
 * @param in        data stored in the log stream that contains the record
 *                  data necessary to restore the row.
 *
 * @exception StandardException Standard Derby error policy
 * @exception IOException Method may read from InputStream
 */
public Page findUndo(Transaction rawtran, LogicalUndoable pageOp, LimitObjectInput in) throws StandardException, IOException {
    ControlRow root = null;
    ControlRow control_row = null;
    DataValueDescriptor[] logged_index_row_template = null;
    DataValueDescriptor[] template = null;
    Page ret_page = null;
    ContainerHandle container = pageOp.getContainer();
    RecordHandle rechandle = pageOp.getRecordHandle();
    boolean ok_exit = false;
    int compare_result = 1;
    B2I btree = null;
    try {
        // Need Conglomerate to create templates - get from the root page.
        root = ControlRow.get(container, BTree.ROOTPAGEID);
        if (SanityManager.DEBUG)
            SanityManager.ASSERT(root.getPage().isLatched());
        btree = (B2I) root.getConglom(B2I.FORMAT_NUMBER);
        if (SanityManager.DEBUG)
            SanityManager.ASSERT(btree instanceof B2I);
        // create a template for the logged index row from the conglomerate.
        logged_index_row_template = btree.createTemplate(rawtran);
        // create a template for the page index row from the conglomerate.
        template = btree.createTemplate(rawtran);
    } finally {
        if (root != null)
            root.release();
    }
    // Get logged row from record.
    pageOp.restoreLoggedRow(logged_index_row_template, in);
    // RESOLVE (mikem) - currently restoreLoggedRow() may latch and unlatch
    // a page in the container (see ST059).
    // Now get the page where the record used to be.
    ok_exit = false;
    try {
        // "open" the btree, using recovery's already opened container
        OpenBTree open_btree = new OpenBTree();
        open_btree.init(// current user xact - not needed
        (TransactionManager) null, // current xact      - not needed
        (TransactionManager) null, // recovery already opened container
        pageOp.getContainer(), rawtran, false, ContainerHandle.MODE_FORUPDATE, // already opened.
        TransactionManager.MODE_NONE, // don't get locks during undo
        (BTreeLockingPolicy) null, btree, // no logical undo necessary, as
        (LogicalUndo) null, // this code only does read.
        (DynamicCompiledOpenConglomInfo) null);
        // System.out.println(
        // "calling logical undo, recordhandle = " + rechandle);
        // System.out.println("calling logical undo, record= " +
        // logged_index_row_template);
        // Get the page where the record was originally, before splits
        // could have possibly moved it.
        control_row = ControlRow.get(open_btree, rechandle.getPageNumber());
        // init compare_result, if record doesn't exist do the search
        compare_result = 1;
        if (control_row.getPage().recordExists(rechandle, true)) {
            if (SanityManager.DEBUG) {
                SanityManager.ASSERT(control_row.getPage().fetchNumFields(rechandle) == logged_index_row_template.length);
            }
            // create template for the page index row from the conglomerate.
            RecordHandle ret_rechandle = control_row.getPage().fetchFromSlot((RecordHandle) null, control_row.getPage().getSlotNumber(rechandle), template, (FetchDescriptor) null, true);
            // compare the 2 rows, and if they are the same then the raw
            // store has the right page and record and there is no work to
            // be done (this is usual case).
            compare_result = ControlRow.compareIndexRowToKey(template, logged_index_row_template, logged_index_row_template.length, 1, open_btree.getColumnSortOrderInfo());
        }
        if (compare_result == 0) {
            ret_page = control_row.getPage();
        } else {
            // if the 2 don't compare equal, search the btree from the root
            // for the logged row, find the leaf, reset the row for the raw
            // store, and return the new page latched.
            // Create the objects needed for the insert.
            SearchParameters sp = new SearchParameters(logged_index_row_template, ScanController.GE, template, open_btree, false);
            control_row.release();
            control_row = null;
            control_row = ControlRow.get(open_btree, BTree.ROOTPAGEID).search(sp);
            if (!sp.resultExact) {
                if (SanityManager.DEBUG) {
                    SanityManager.THROWASSERT("B2IUndo - could not find key being searched for:" + ";key = " + RowUtil.toString(logged_index_row_template) + ";sp = " + sp + "control_row = " + control_row + "control_row.debugPage() = " + control_row.debugPage(open_btree) + "control_row.getPage() = " + control_row.getPage());
                }
                throw StandardException.newException(SQLState.BTREE_ROW_NOT_FOUND_DURING_UNDO);
            } else {
                RecordHandle rh = control_row.getPage().fetchFromSlot((RecordHandle) null, sp.resultSlot, new DataValueDescriptor[0], (FetchDescriptor) null, true);
                pageOp.resetRecordHandle(rh);
                ret_page = control_row.getPage();
            }
        }
        ok_exit = true;
    } finally {
        // pageOp.getRecordHandle());
        if ((!ok_exit) && (control_row != null))
            control_row.release();
    }
    return (ret_page);
}
Also used : OpenBTree(org.apache.derby.impl.store.access.btree.OpenBTree) SearchParameters(org.apache.derby.impl.store.access.btree.SearchParameters) ControlRow(org.apache.derby.impl.store.access.btree.ControlRow) RecordHandle(org.apache.derby.iapi.store.raw.RecordHandle) Page(org.apache.derby.iapi.store.raw.Page) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor) ContainerHandle(org.apache.derby.iapi.store.raw.ContainerHandle)

Aggregations

ContainerHandle (org.apache.derby.iapi.store.raw.ContainerHandle)1 Page (org.apache.derby.iapi.store.raw.Page)1 RecordHandle (org.apache.derby.iapi.store.raw.RecordHandle)1 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)1 ControlRow (org.apache.derby.impl.store.access.btree.ControlRow)1 OpenBTree (org.apache.derby.impl.store.access.btree.OpenBTree)1 SearchParameters (org.apache.derby.impl.store.access.btree.SearchParameters)1