Search in sources :

Example 6 with Page

use of org.apache.derby.iapi.store.raw.Page in project derby by apache.

the class HeapController method doInsert.

/**
 * Insert a new row into the heap.
 * <p>
 * Overflow policy:
 * The current heap access method implements an algorithm that optimizes
 * for fetch efficiency vs. space efficiency.  A row will not be over
 * flowed unless it is bigger than a page.  If it is bigger than a page
 * then it's initial part will be placed on a page and then subsequent
 * parts will be overflowed to other pages.
 * <p>
 *
 * @return The record handle of the inserted row.
 *
 * @param row           The row to insert.
 *
 * @exception  StandardException  Standard exception policy.
 */
private RecordHandle doInsert(DataValueDescriptor[] row) throws StandardException {
    Page page = null;
    byte insert_mode;
    RecordHandle rh;
    if (SanityManager.DEBUG) {
        Heap heap = (Heap) open_conglom.getConglomerate();
        // Make sure valid columns are in the list.  The RowUtil
        // call is too expensive to make in a released system for
        // every insert.
        int invalidColumn = RowUtil.columnOutOfRange(row, null, heap.format_ids.length);
        if (invalidColumn >= 0) {
            throw (StandardException.newException(SQLState.HEAP_TEMPLATE_MISMATCH, invalidColumn, heap.format_ids.length));
        }
    }
    // Get the last page that was returned for insert or the last page
    // that was allocated.
    page = open_conglom.getContainer().getPageForInsert(0);
    if (page != null) {
        // if there are 0 rows on the page allow the insert to overflow.
        insert_mode = (page.recordCount() == 0) ? Page.INSERT_OVERFLOW : Page.INSERT_DEFAULT;
        // Check to see if there is enough space on the page
        // for the row.
        rh = page.insert(row, null, insert_mode, AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD);
        page.unlatch();
        page = null;
        // insert it and release exclusive access to the page.
        if (rh != null) {
            return rh;
        }
    }
    // If the last inserted page is now full, or RawStore have
    // forgotten what it was, or the row cannot fit on the last
    // inserted page, try to have rawStore get a relatively unfilled
    // page.
    page = open_conglom.getContainer().getPageForInsert(ContainerHandle.GET_PAGE_UNFILLED);
    if (page != null) {
        // Do the insert all over again hoping that it will fit into
        // this page, and if not, allocate a new page.
        // if there are 0 rows on the page allow the insert to overflow.
        insert_mode = (page.recordCount() == 0) ? Page.INSERT_OVERFLOW : Page.INSERT_DEFAULT;
        rh = page.insert(row, null, insert_mode, AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD);
        page.unlatch();
        page = null;
        // insert it and release exclusive access to the page.
        if (rh != null) {
            return rh;
        }
    }
    page = open_conglom.getContainer().addPage();
    // At this point with long rows the raw store will guarantee
    // that any size row will fit on an empty page.
    rh = page.insert(row, null, Page.INSERT_OVERFLOW, AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD);
    page.unlatch();
    page = null;
    if (SanityManager.DEBUG) {
        // a null will only be returned if this page is not empty
        SanityManager.ASSERT(rh != null);
    }
    return rh;
}
Also used : RecordHandle(org.apache.derby.iapi.store.raw.RecordHandle) Page(org.apache.derby.iapi.store.raw.Page)

Example 7 with Page

use of org.apache.derby.iapi.store.raw.Page in project derby by apache.

the class BTreePostCommit method purgeCommittedDeletes.

/**
 * Reclaim space taken up by committed deleted rows.
 * <p>
 * This routine assumes it has been called by an internal transaction which
 * has performed no work so far, and that it has an exclusive table lock.
 * These assumptions mean that any deleted rows encountered must be from
 * committed transactions (otherwise we could not have gotten the exclusive
 * table lock).
 * <p>
 * This routine handles purging committed deletes while holding a table
 * level exclusive lock.  See purgeRowLevelCommittedDeletes() for row level
 * purging.
 *
 * @param open_btree The btree already opened.
 * @param pageno The page number of the page to look for committed deletes.
 *
 * @exception  StandardException  Standard exception policy.
 */
private final DataValueDescriptor[] purgeCommittedDeletes(OpenBTree open_btree, long pageno) throws StandardException {
    ControlRow control_row = null;
    DataValueDescriptor[] shrink_key = null;
    try {
        // The following can fail either if it can't get the latch or
        // somehow the page requested no longer exists.  In either case
        // the post commit work will just skip it.
        control_row = ControlRow.getNoWait(open_btree, pageno);
        if (control_row != null) {
            Page page = control_row.page;
            // The number records that can be reclaimed is:
            // total recs - control row - recs_not_deleted
            int num_possible_commit_delete = page.recordCount() - 1 - page.nonDeletedRecordCount();
            if (num_possible_commit_delete > 0) {
                // have already looked at).
                for (int slot_no = page.recordCount() - 1; slot_no > 0; slot_no--) {
                    if (page.isDeletedAtSlot(slot_no)) {
                        if (page.recordCount() == 2) {
                            // About to purge last row from page so
                            // remember the key so we can shrink the
                            // tree.
                            shrink_key = this.getShrinkKey(open_btree, control_row, slot_no);
                        }
                        page.purgeAtSlot(slot_no, 1, true);
                        // Tell scans positioned on this page to reposition
                        // because the row they are positioned on may have
                        // disappeared.
                        page.setRepositionNeeded();
                        if (SanityManager.DEBUG) {
                            if (SanityManager.DEBUG_ON("verbose_btree_post_commit")) {
                                System.out.println("Purging row[" + slot_no + "]" + "on page:" + pageno + ".\n");
                            }
                        }
                    }
                }
            }
            if (page.recordCount() == 1) {
                if (SanityManager.DEBUG) {
                    if (SanityManager.DEBUG_ON("verbose_btree_post_commit")) {
                        System.out.println("Chance to shrink.\n");
                    }
                }
            }
        } else {
            if (SanityManager.DEBUG) {
                if (SanityManager.DEBUG_ON("verbose_btree_post_commit")) {
                    System.out.println("Get No Wait returned null. page num = " + pageno + "\n");
                }
            }
        }
    } finally {
        if (control_row != null)
            control_row.release();
    }
    return (shrink_key);
}
Also used : Page(org.apache.derby.iapi.store.raw.Page) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor)

Example 8 with Page

use of org.apache.derby.iapi.store.raw.Page 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)

Example 9 with Page

use of org.apache.derby.iapi.store.raw.Page in project derby by apache.

the class HeapPostCommit method purgeCommittedDeletes.

/**
 ************************************************************************
 * Private/Protected methods of This class:
 **************************************************************************
 */
/**
 * Reclaim space taken of committed deleted rows or aborted inserted rows.
 * <p>
 * This routine assumes it has been called by an internal transaction which
 * has performed no work so far, and that it has an exclusive intent table
 * lock.  It will attempt obtain exclusive row locks on rows marked
 * deleted, where successful those rows can be reclaimed as they must be
 * "committed deleted" or "aborted inserted" rows.
 * <p>
 * This routine will latch the page and hold the latch due to interface
 * requirement from Page.purgeAtSlot.
 *
 * @param heap_control  The heap, already opened.
 * @param pageno        number of page to look for committed deletes.
 *
 * @see Page#purgeAtSlot
 * @exception  StandardException  Standard exception policy.
 */
private final void purgeCommittedDeletes(HeapController heap_control, long pageno) throws StandardException {
    // The following can fail either if it can't get the latch or
    // somehow the page requested no longer exists.
    // resolve - what will happen if the user page doesnt exist
    // wait to get the latch on the page
    Page page = heap_control.getUserPageWait(pageno);
    boolean purgingDone = false;
    if (page != null) {
        try {
            // The number records that can be reclaimed is:
            // total recs - recs_not_deleted
            int num_possible_commit_delete = page.recordCount() - page.nonDeletedRecordCount();
            if (num_possible_commit_delete > 0) {
                // have already looked at).
                for (int slot_no = page.recordCount() - 1; slot_no >= 0; slot_no--) {
                    boolean row_is_committed_delete = page.isDeletedAtSlot(slot_no);
                    if (row_is_committed_delete) {
                        // At this point we only know that the row is
                        // deleted, not whether it is committed.
                        // see if we can purge the row, by getting an
                        // exclusive lock on the row.  If it is marked
                        // deleted and we can get this lock, then it
                        // must be a committed delete and we can purge
                        // it.
                        RecordHandle rh = page.fetchFromSlot((RecordHandle) null, slot_no, RowUtil.EMPTY_ROW, RowUtil.EMPTY_ROW_FETCH_DESCRIPTOR, true);
                        row_is_committed_delete = heap_control.lockRowAtSlotNoWaitExclusive(rh);
                        if (row_is_committed_delete) {
                            purgingDone = true;
                            page.purgeAtSlot(slot_no, 1, false);
                            if (SanityManager.DEBUG) {
                                if (SanityManager.DEBUG_ON("verbose_heap_post_commit")) {
                                    SanityManager.DEBUG_PRINT("HeapPostCommit", "Purging row[" + slot_no + "]" + "on page:" + pageno + ".\n");
                                }
                            }
                        }
                    }
                }
            }
            if (page.recordCount() == 0) {
                purgingDone = true;
                // Deallocate the current page with 0 rows on it.
                heap_control.removePage(page);
                if (SanityManager.DEBUG) {
                    if (SanityManager.DEBUG_ON("verbose_heap_post_commit")) {
                        SanityManager.DEBUG_PRINT("HeapPostCommit", "Calling Heap removePage().; pagenumber=" + pageno + "\n");
                    }
                }
            }
        } finally {
            // would cause a subquent undo of the purge to fail.
            if (!purgingDone) {
                page.unlatch();
                page = null;
            }
        }
    } else {
        if (SanityManager.DEBUG) {
            if (SanityManager.DEBUG_ON("verbose_heap_post_commit")) {
                SanityManager.DEBUG_PRINT("HeapPostCommit", "Get No Wait returned null. page num = " + pageno + "\n");
                SanityManager.showTrace(new Throwable());
            }
        }
    }
    return;
}
Also used : RecordHandle(org.apache.derby.iapi.store.raw.RecordHandle) Page(org.apache.derby.iapi.store.raw.Page)

Example 10 with Page

use of org.apache.derby.iapi.store.raw.Page in project derby by apache.

the class GenericScanController method replace.

/**
 *    @see org.apache.derby.iapi.store.access.ScanController#replace
 */
public boolean replace(DataValueDescriptor[] row, FormatableBitSet validColumns) throws StandardException {
    repositionScanForUpateOper();
    Page page = scan_position.current_page;
    int slot = scan_position.current_slot;
    if (SanityManager.DEBUG) {
        // DERBY-2197: Previously, we would try to get an exclusive row
        // lock here when the container was opened in row locking mode. In
        // most cases, the container is not opened in row locking mode. If
        // it is, and the open conglomerate uses update locks,
        // repositionScanForUpateOper() has already obtained an exclusive
        // row lock. We don't expect this method to be called unless these
        // conditions are satisfied, so now we just assert that no row
        // locking is required at this point.
        SanityManager.ASSERT(((open_conglom.getContainer().getLockingPolicy().getMode() != LockingPolicy.MODE_RECORD) || (open_conglom.isUseUpdateLocks())), "Current mode of container requires row locking.");
        // make sure current_rh and current_slot are in sync
        SanityManager.ASSERT(slot == page.getSlotNumber(scan_position.current_rh));
    }
    boolean ret_val;
    if (page.isDeletedAtSlot(slot)) {
        ret_val = false;
    } else {
        page.updateAtSlot(slot, row, validColumns);
        ret_val = true;
    }
    scan_position.unlatch();
    return (ret_val);
}
Also used : Page(org.apache.derby.iapi.store.raw.Page)

Aggregations

Page (org.apache.derby.iapi.store.raw.Page)28 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)11 ContainerHandle (org.apache.derby.iapi.store.raw.ContainerHandle)10 RecordHandle (org.apache.derby.iapi.store.raw.RecordHandle)9 FetchDescriptor (org.apache.derby.iapi.store.raw.FetchDescriptor)5 LockingPolicy (org.apache.derby.iapi.store.raw.LockingPolicy)4 ContainerKey (org.apache.derby.iapi.store.raw.ContainerKey)3 Transaction (org.apache.derby.iapi.store.raw.Transaction)2 RawContainerHandle (org.apache.derby.iapi.store.raw.data.RawContainerHandle)2 OpenConglomerate (org.apache.derby.impl.store.access.conglomerate.OpenConglomerate)2 BasePage (org.apache.derby.impl.store.raw.data.BasePage)2 Properties (java.util.Properties)1 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)1 DynamicCompiledOpenConglomInfo (org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo)1 TransactionManager (org.apache.derby.iapi.store.access.conglomerate.TransactionManager)1 PageKey (org.apache.derby.iapi.store.raw.PageKey)1 PageTimeStamp (org.apache.derby.iapi.store.raw.PageTimeStamp)1 RawStoreFactory (org.apache.derby.iapi.store.raw.RawStoreFactory)1 StreamContainerHandle (org.apache.derby.iapi.store.raw.StreamContainerHandle)1 RawTransaction (org.apache.derby.iapi.store.raw.xact.RawTransaction)1