Search in sources :

Example 21 with Page

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

the class BTreeScan method savePositionAndReleasePage.

/**
 * Save the current scan position by key and release the latch on the leaf
 * that's being scanned. This method should be called if the latch on a
 * leaf needs to be released in the middle of the scan. The scan can
 * later reposition to the saved position by calling {@code reposition()}.
 *
 * @param partialKey known parts of the key that should be saved, or
 * {@code null} if the entire key is unknown and will have to be fetched
 * from the page
 * @param vcols an array which tells which columns of the partial key are
 * valid (key columns that have 0 in this array are not valid, and their
 * values must be fetched from the page), or {@code null} if all the
 * columns are valid
 * @throws StandardException if an error occurs while saving the position
 * @see #reposition(BTreeRowPosition, boolean)
 */
void savePositionAndReleasePage(DataValueDescriptor[] partialKey, int[] vcols) throws StandardException {
    final Page page = scan_position.current_leaf.getPage();
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(page.isLatched(), "Page is not latched");
        SanityManager.ASSERT(scan_position.current_positionKey == null, "Scan position already saved");
        if (partialKey == null) {
            SanityManager.ASSERT(vcols == null);
        }
        if (vcols != null) {
            SanityManager.ASSERT(partialKey != null);
            SanityManager.ASSERT(vcols.length <= partialKey.length);
        }
    }
    try {
        DataValueDescriptor[] fullKey = scan_position.getKeyTemplate();
        FetchDescriptor fetchDescriptor = null;
        boolean haveAllColumns = false;
        if (partialKey != null) {
            int copiedCols = 0;
            final int partialKeyLength = (vcols == null) ? partialKey.length : vcols.length;
            for (int i = 0; i < partialKeyLength; i++) {
                if (vcols == null || vcols[i] != 0) {
                    fullKey[i].setValue(partialKey[i]);
                    copiedCols++;
                }
            }
            if (copiedCols < fullKey.length) {
                fetchDescriptor = scan_position.getFetchDescriptorForSaveKey(vcols, fullKey.length);
            } else {
                haveAllColumns = true;
            }
        }
        if (!haveAllColumns) {
            RecordHandle rh = page.fetchFromSlot((RecordHandle) null, scan_position.current_slot, fullKey, fetchDescriptor, true);
            if (SanityManager.DEBUG) {
                SanityManager.ASSERT(rh != null, "Row not found");
            }
        }
        scan_position.current_positionKey = fullKey;
        // Don't null out current_rh, we might be able to use it later if
        // no rows are moved off the page.
        // scan_position.current_rh = null;
        scan_position.versionWhenSaved = page.getPageVersion();
        scan_position.current_slot = Page.INVALID_SLOT_NUMBER;
    } finally {
        scan_position.current_leaf.release();
        scan_position.current_leaf = null;
    }
}
Also used : FetchDescriptor(org.apache.derby.iapi.store.raw.FetchDescriptor) RecordHandle(org.apache.derby.iapi.store.raw.RecordHandle) Page(org.apache.derby.iapi.store.raw.Page) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor)

Example 22 with Page

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

the class BTreeScan method reposition.

/**
 * Reposition the scan leaving and reentering the access layer.
 * <p>
 * When a scan leaves access it saves the RecordHandle of the record
 * on the page.  There are 2 cases to consider when trying to reposition
 * the scan when re-entering access:
 *     o ROW has not moved off the page.
 *       If the row has not moved then the RecordHandle we have saved
 *       away is valid, and we just call RawStore to reposition on that
 *       RecordHandle (RawStore takes care of the row moving within
 *       the page).
 *     o ROW has moved off the page.
 *       This can only happen in the case of a btree split.  In that
 *       case the splitter will have caused all scans positioned on
 *       this page within the same transaction to save a copy of the
 *       row that the scan was positioned on.  Then to reposition the
 *       scan it is necessary to research the tree from the top using
 *       the copy of the row.
 *
 * There are a few cases where it is possible that
 * the key no longer exists in the table.  In the case of a scan held
 * open across commit it is easy to imagine that the row the scan was
 * positioned on could be deleted and subsequently purged from the table
 * all before the scan resumes.  Also in the case of read uncommitted
 * the scan holds no lock on the current row, so it could be purged -
 * in the following scenario for instance:  read uncommitted transaction 1
 * opens scan and positions on row (1,2), transaction 2 deletes (1,2) and
 * commits, transaction 1 inserts (1,3) which goes to same page as (1,2)
 * and is going to cause a split, transaction 1 saves scan position as
 * key, and then purges row (1, 2), when transaction
 * 1 resumes scan (1, 2) no longer exists.  missing_row_for_key_ok
 * parameter is added as a sanity check to make sure it ok that
 * repositioning does not go to same row that we were repositioned on.
 *
 * @param   pos                     position to set the scan to.
 *
 * @param   missing_row_for_key_ok  if true and exact key is not found then
 *                                  scan is just set to key just left of
 *                                  the key (thus a next will move to the
 *                                  key just after "pos")
 *
 * @return  returns true if scan has been repositioned successfully, else
 *          returns false if the position key could not be found and
 *          missing_row_for_key_ok was false indicating that scan could
 *          only be positioned on the exact key match.
 *
 * @exception  StandardException  Standard exception policy.
 */
protected boolean reposition(BTreeRowPosition pos, boolean missing_row_for_key_ok) throws StandardException {
    if (this.scan_state != SCAN_INPROGRESS) {
        throw StandardException.newException(SQLState.BTREE_SCAN_NOT_POSITIONED, this.scan_state);
    }
    // positionKey is always valid
    if (SanityManager.DEBUG) {
        if (pos.current_positionKey == null)
            SanityManager.THROWASSERT("pos.current_rh  = (" + pos.current_rh + "), " + "pos.current_positionKey = (" + pos.current_positionKey + ").");
    }
    if (pos.current_positionKey == null) {
        throw StandardException.newException(SQLState.BTREE_SCAN_INTERNAL_ERROR, (pos.current_rh == null), (pos.current_positionKey == null));
    }
    // from the root of the B-tree in the common case.
    if (pos.current_rh != null) {
        // Reposition to remembered spot on page.
        // Get the page object. If getPage() returns null, the page is
        // not valid (could for instance have been removed by compress
        // table) so we need to reposition by key instead.
        Page page = container.getPage(pos.current_rh.getPageNumber());
        if (page != null) {
            ControlRow row = ControlRow.getControlRowForPage(container, page);
            if (row instanceof LeafControlRow && !row.page.isRepositionNeeded(pos.versionWhenSaved)) {
                // No rows have been moved off the page after we released
                // the latch, and the page is still a leaf page. No need
                // to reposition by key.
                pos.current_leaf = (LeafControlRow) row;
                pos.current_slot = row.page.getSlotNumber(pos.current_rh);
                pos.current_positionKey = null;
                return true;
            }
            // We couldn't use the position specified by current_rh, so we
            // need to reposition by key and may find the row on another
            // page. Therefore, give up the latch on this page.
            row.release();
        }
    }
    SearchParameters sp = new SearchParameters(pos.current_positionKey, // this is a full key search, so this arg is not used.
    SearchParameters.POSITION_LEFT_OF_PARTIAL_KEY_MATCH, init_template, this, false);
    pos.current_leaf = (LeafControlRow) ControlRow.get(this, BTree.ROOTPAGEID).search(sp);
    if (!sp.resultExact && !missing_row_for_key_ok) {
        // Did not find key to exactly position on.
        pos.current_leaf.release();
        pos.current_leaf = null;
        return (false);
    }
    pos.current_slot = sp.resultSlot;
    // so we don't set it here if its old value is null.
    if (pos.current_rh != null) {
        pos.current_rh = pos.current_leaf.page.getRecordHandleAtSlot(pos.current_slot);
    }
    pos.current_positionKey = null;
    return (true);
}
Also used : Page(org.apache.derby.iapi.store.raw.Page)

Example 23 with Page

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

the class BranchControlRow method allocate.

/**
 * Allocate a new leaf page to the conglomerate.
 *
 * @exception StandardException Standard exception policy.
 */
private static BranchControlRow allocate(OpenBTree open_btree, ControlRow leftchild, int level, ControlRow parent) throws StandardException {
    Page page = open_btree.container.addPage();
    // Create a control row for the new page.
    BranchControlRow control_row = new BranchControlRow(open_btree, page, level, parent, false, leftchild.page.getPageNumber());
    // Insert the control row on the page.
    byte insertFlag = Page.INSERT_INITIAL;
    insertFlag |= Page.INSERT_DEFAULT;
    page.insertAtSlot(Page.FIRST_SLOT_NUMBER, control_row.getRow(), (FormatableBitSet) null, (LogicalUndo) null, insertFlag, AccessFactoryGlobals.BTREE_OVERFLOW_THRESHOLD);
    // Page is returned latched.
    return (control_row);
}
Also used : Page(org.apache.derby.iapi.store.raw.Page)

Example 24 with Page

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

the class D_BTreeController method diag_page.

/* Private/Protected methods of This class: */
private static void diag_page(OpenBTree open_btree, ControlRow control_row, Properties prop, LevelInfo[] level_info) throws StandardException {
    LevelInfo li = level_info[control_row.getLevel()];
    Page page = control_row.page;
    li.num_pages++;
    li.num_entries += (page.recordCount() - 1);
    li.num_deleted += (page.recordCount() - page.nonDeletedRecordCount());
    li.max_pageno = Math.max(li.max_pageno, page.getPageNumber());
    DiagnosticUtil.findDiagnostic(page).diag_detail(prop);
    DiagnosticUtil.findDiagnostic(page).diag_detail(prop);
    // number of free bytes on page.
    int free_bytes = Integer.parseInt(prop.getProperty(Page.DIAG_BYTES_FREE));
    li.num_free_bytes += free_bytes;
    // number of bytes reserved on page.
    int res_bytes = Integer.parseInt(prop.getProperty(Page.DIAG_BYTES_RESERVED));
    li.num_res_bytes += res_bytes;
    // overflow rows.
    int overflow = Integer.parseInt(prop.getProperty(Page.DIAG_NUMOVERFLOWED));
    li.num_overflow_rows += overflow;
    // size of rows.
    int rowsize = Integer.parseInt(prop.getProperty(Page.DIAG_ROWSIZE));
    li.num_rowsize_bytes += rowsize;
    // size of slot table.
    int slottable_size = Integer.parseInt(prop.getProperty(Page.DIAG_SLOTTABLE_SIZE));
    li.num_slottab_bytes += slottable_size;
    // minimum row size.
    int min_rowsize = Integer.parseInt(prop.getProperty(Page.DIAG_MINROWSIZE));
    li.min_rowsize_bytes = Math.min(li.min_rowsize_bytes, min_rowsize);
    // maximum row size.
    int max_rowsize = Integer.parseInt(prop.getProperty(Page.DIAG_MAXROWSIZE));
    li.max_rowsize_bytes = Math.max(li.max_rowsize_bytes, max_rowsize);
}
Also used : Page(org.apache.derby.iapi.store.raw.Page)

Example 25 with Page

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

the class LeafControlRow method allocate.

/* Private/Protected methods of This class: */
/**
 * Allocate a new leaf page to the conglomerate.
 *
 * @param btree     The open conglomerate from which to get the leaf from
 * @param parent    The parent page of the newly allocated page, null if
 *                  allocating root page.
 *
 * @exception StandardException Standard exception policy.
 */
private static LeafControlRow allocate(OpenBTree btree, ControlRow parent) throws StandardException {
    Page page = btree.container.addPage();
    // Create a control row for the new page.
    LeafControlRow control_row = new LeafControlRow(btree, page, parent, false);
    // Insert the control row on the page, in the first slot on the page.
    // This operation is only done as part of a new tree or split, which
    // which both will be undone physically so no logical undo record is
    // needed.
    byte insertFlag = Page.INSERT_INITIAL;
    insertFlag |= Page.INSERT_DEFAULT;
    RecordHandle rh = page.insertAtSlot(Page.FIRST_SLOT_NUMBER, control_row.getRow(), (FormatableBitSet) null, (LogicalUndo) null, insertFlag, AccessFactoryGlobals.BTREE_OVERFLOW_THRESHOLD);
    if (SanityManager.DEBUG) {
        RecordHandle rh2 = null;
        rh2 = page.fetchFromSlot((RecordHandle) null, page.FIRST_SLOT_NUMBER, new DataValueDescriptor[0], (FetchDescriptor) null, true);
        SanityManager.ASSERT(rh.getId() == rh2.getId() && rh.getPageNumber() == rh2.getPageNumber());
    }
    // Page is returned latched.
    return (control_row);
}
Also used : RecordHandle(org.apache.derby.iapi.store.raw.RecordHandle) FetchDescriptor(org.apache.derby.iapi.store.raw.FetchDescriptor) Page(org.apache.derby.iapi.store.raw.Page) DataValueDescriptor(org.apache.derby.iapi.types.DataValueDescriptor)

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