⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 genericscancontroller.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/*   Derby - Class org.apache.derby.impl.store.access.conglomerate.GenericScanController   Copyright 2000, 2004 The Apache Software Foundation or its licensors, as applicable.   Licensed under the Apache License, Version 2.0 (the "License");   you may not use this file except in compliance with the License.   You may obtain a copy of the License at      http://www.apache.org/licenses/LICENSE-2.0   Unless required by applicable law or agreed to in writing, software   distributed under the License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   See the License for the specific language governing permissions and   limitations under the License. */package org.apache.derby.impl.store.access.conglomerate;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.error.StandardException; import org.apache.derby.iapi.store.access.conglomerate.Conglomerate;import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;import org.apache.derby.iapi.store.access.conglomerate.ScanManager;import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;import org.apache.derby.iapi.store.access.ConglomerateController;import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo;import org.apache.derby.iapi.store.access.Qualifier;import org.apache.derby.iapi.store.access.RowUtil;import org.apache.derby.iapi.store.access.ScanController;import org.apache.derby.iapi.store.access.ScanInfo;import org.apache.derby.iapi.store.access.SpaceInfo;import org.apache.derby.iapi.store.raw.ContainerHandle;import org.apache.derby.iapi.store.raw.FetchDescriptor;import org.apache.derby.iapi.store.raw.Page;import org.apache.derby.iapi.store.raw.RecordHandle;import org.apache.derby.iapi.store.raw.Transaction;import org.apache.derby.iapi.store.access.Qualifier;import org.apache.derby.iapi.types.DataValueDescriptor;import org.apache.derby.iapi.types.Orderable;import org.apache.derby.iapi.types.RowLocation;import org.apache.derby.iapi.store.access.BackingStoreHashtable;import org.apache.derby.iapi.services.io.FormatableBitSet;import java.util.Properties; /**Generic class implementing shared ScanController methods.Logically a scancontroller is used to scan a set of rows that meet some specified qualification.  Rows that meet the qualification may be operatedupon by the scan to fetch, delete, or replace.  The ScanController alsosupports the notion or "repositioning" the scan, which simply resets thebeginning of the scan to a new place, and allows the user to continue fromthere.This class attempts to abstract out some of the parts of the scan such thatmaybe multiple access methods can share code, even if they perform parts ofthe scan wildly differently.  Here is how the scan has been broken apart:scan_position - this variable holds the current scan position, it may be                 extended                to provide more information if necessary.scan_state    - a scan has 3 possible states:                 SCAN_INIT, SCAN_INPROGRESS, SCAN_DONEpositionAtInitScan()              - This routine is called to move the scan to the SCAN_INIT state.                It is used both for initialization of the ScanController and                by reopenScan().positionAtStartForForwardScan()              - This routine is called to move the scan from SCAN_INIT to                 SCAN_INPROGRESS.  Upon return from this routine it is expected                that scan_position is set such that calling the generic                 scan loop will reach the first row of the scan.  Note that this                usually means setting the scan_postion to one before the 1st                 row to be returned.fetchRows()   - This routine is the meat of the scan, it moves the scan to the                next row, applies necessary qualifiers, and handles group or                non-group operations.  It moves through rows on a page in                order and then moves to the "next" page.positionAtNextPage()              - This routine handles moving the scan from the current                 scan_position to the next page.positionAtDoneScan()              - Handle all cleanup associated with moving the scan state from                SCAN_INPROGRESS to SCAN_DONE.  This may include releasing locks,                and setting the state of the scan.  This does not close the                 scan, it allows for a reopenScan() to be called.**/public abstract class GenericScanController     extends GenericController implements ScanManager{    /**************************************************************************     * Constants of the class     **************************************************************************     */    /*     * There are 5 states a scan can be in.     *     SCAN_INIT - A scan has started but no positioning has been done.     *                 The scan will be positioned when the first next() call     *                 has been made.  None of the positioning state variables     *                 are valid in this state.     *     SCAN_INPROGRESS -     *                 A scan is in this state after the first next() call.     *                 On exit from any GenericScanController method, while in      *                 this state,     *                 the scan "points" at a row which qualifies for the      *                 scan.  While not maintaining latches on a page the      *                 current position of the scan is either kept by record     *                 handle or key.  To tell which use the following:     *                 if (record key == null)     *                    record handle has current position     *                 else     *                    record key has current position     *     *     SCAN_DONE - Once the end of the table or the stop condition is met     *                 then the scan is placed in this state.  Only valid      *                 ScanController method at this point is close().     *     *     SCAN_HOLD_INIT -     *                 The scan has been opened and held open across a commit,     *                 at the last commit the state was SCAN_INIT.     *                 The scan has never progressed from the SCAN_INIT state     *                 during a transaction.  When a next is done the state     *                 will either progress to SCAN_INPROGRESS or SCAN_DONE.     *     *     SCAN_HOLD_INPROGRESS -     *                 The scan has been opened and held open across a commit,     *                 at the last commit the state was in SCAN_INPROGRESS.     *                 The transaction which opened the scan has committed,     *                 but the scan was opened with the "hold" option true.     *                 At commit the locks were released and the "current"     *                 position is remembered.  In this state only two calls     *                 are valid, either next() or close().  When next() is     *                 called the scan is reopened, the underlying container     *                 is opened thus associating all new locks with the current     *                 transaction, and the scan continues at the "next" row.     */    public static final int    SCAN_INIT             = 1;    public static final int    SCAN_INPROGRESS       = 2;    public static final int    SCAN_DONE             = 3;    public static final int    SCAN_HOLD_INIT        = 4;    public static final int    SCAN_HOLD_INPROGRESS  = 5;    /**************************************************************************     * Fields of the class     **************************************************************************     */    /**     * The following group of fields are all basic input parameters which are     * provided by the calling code when doing a scan.     * These are just saved values from what was initially input.     **/	private FormatableBitSet                 init_scanColumnList;    private DataValueDescriptor[]   init_startKeyValue;    private int                     init_startSearchOperator;    private Qualifier[][]           init_qualifier;    private DataValueDescriptor[]   init_stopKeyValue;    private int                     init_stopSearchOperator;    private FetchDescriptor init_fetchDesc;    /**     * Delay positioning the table at the start position until the first     * next() call.     */    private int         scan_state;        /**     * The position for the current scan.  The can be maintained in any     * of the following ways:     *     record handle - scan_position.current_rh:     *         The scan maintains it's position using the record handle while     *         it does not have a latch on the page, which is the case anytime     *         control leaves access.  The access method must take appropriate     *         steps to make sure the record handle will still be valid when     *         the scan needs to reposition using the record handle.     *     slot number   - scan_position.current_slot:     *         While the scan has a latch on the page the scan is positioned     *         using the slot number as the order of the rows cannot change     *         while the latch is held (unless the holder of the latch causes     *         them to move).       *     page number   - (RESOLVE - TODO)     *         Sometimes it would be interesting to position a scan "between"     *         pages, such that the next time the scan starts is starts at     *         the next page.  This would allow us to efficiently do group     *         scans returning page at atime results.       *         NOT IMPLEMENTED CURRENTLY.     **/    protected RowPosition         scan_position;    /**     * Performance counters ...     */    protected int stat_numpages_visited         = 0;    protected int stat_numrows_visited          = 0;    protected int stat_numrows_qualified        = 0;    /**************************************************************************     * Constructors for This class:     **************************************************************************     */    /**************************************************************************     * Private methods of This class:     **************************************************************************     */    private final void repositionScanForUpateOper()		throws StandardException    {        if (scan_state != SCAN_INPROGRESS)            throw StandardException.newException(                    SQLState.AM_SCAN_NOT_POSITIONED);        if (!open_conglom.latchPage(scan_position))        {            throw StandardException.newException(                    SQLState.AM_RECORD_NOT_FOUND,                     open_conglom.getContainer().getId(),                    new Long(scan_position.current_rh.getId()));        }        if (open_conglom.isUseUpdateLocks())        {            // we only have an U lock at this point which was acquired when the            // scan positioned on the row, need to request an            // X lock before we can actually perform the delete            open_conglom.lockPositionForWrite(                scan_position, false /* not insert */, true);        }    }    /**************************************************************************     * Protected methods implementing mechanics of scanning rows:     *     *     positionAtInitScan()             - move scan state to SCAN_INIT     *     positionAtStartForForwardScan()  - SCAN_INIT -> SCAN_INPROGRESS     *     positionAtResumeScan()           - reposition after losing scan latch     *     fetchRows()                      - move scan while in SCAN_INPROGRESS     *     positionAtNextPage()             - move page while in SCAN_INPROGRESS     *     positionAtDoneScan()             - SCAN_INPROGRESS -> SCAN_DONE     *     **************************************************************************     */    /**     * Move scan to the the SCAN_INIT state.     * <p>     * This routine is called to move the scan to the SCAN_INIT state.     * It is used both for initialization of the ScanController and     * by reopenScan().     **/	protected void positionAtInitScan(    DataValueDescriptor[]   startKeyValue,    int                     startSearchOperator,    Qualifier               qualifier[][],    DataValueDescriptor[]   stopKeyValue,    int                     stopSearchOperator,    RowPosition             pos)        throws StandardException    {        // startKeyValue init.	    this.init_startKeyValue         = startKeyValue;		if (RowUtil.isRowEmpty(this.init_startKeyValue, (FormatableBitSet) null))			this.init_startKeyValue = null;        // startSearchOperator init.	    this.init_startSearchOperator   = startSearchOperator;        // qualifier init.        if ((qualifier != null) && (qualifier .length == 0))            qualifier = null;        this.init_qualifier             = qualifier;        // TODO (mikem) - this could be more efficient, by writing        // code to figure out length of row, but scratch row is cached        // so allocating it here is probably not that bad.        init_fetchDesc =             new FetchDescriptor(              (open_conglom.getRuntimeMem().get_scratch_row()).length,              init_scanColumnList,              init_qualifier);        // stopKeyValue init.	    this.init_stopKeyValue          = stopKeyValue;        if (RowUtil.isRowEmpty(this.init_stopKeyValue, (FormatableBitSet) null))            this.init_stopKeyValue = null;        // stopSearchOperator init.	    this.init_stopSearchOperator    = stopSearchOperator;        // reset the "current" position to starting condition.        pos.init();        // Verify that all columns in start key value, stop key value, and        // qualifiers are present in the list of columns described by the        // scanColumnList.        if (SanityManager.DEBUG)        {            if (init_scanColumnList != null)            {                // verify that all columns specified in qualifiers, start                // and stop positions are specified in the scanColumnList.                                  FormatableBitSet required_cols;                if (qualifier != null)                    required_cols = RowUtil.getQualifierBitSet(qualifier);                else                    required_cols = new FormatableBitSet(0);                // add in start columns                if (this.init_startKeyValue != null)                {					required_cols.grow(this.init_startKeyValue.length);                    for (int i = 0; i < this.init_startKeyValue.length; i++)                        required_cols.set(i);                }                if (this.init_stopKeyValue != null)                {					required_cols.grow(this.init_stopKeyValue.length);                    for (int i = 0; i < this.init_stopKeyValue.length; i++)                        required_cols.set(i);                }                FormatableBitSet required_cols_and_scan_list =                     (FormatableBitSet) required_cols.clone();                required_cols_and_scan_list.and(init_scanColumnList);				// FormatableBitSet equals requires the two FormatableBitSets to be of same				// length.				required_cols.grow(init_scanColumnList.size());                if (!required_cols_and_scan_list.equals(required_cols))                {                    SanityManager.THROWASSERT(                        "Some column specified in a Btree " +                        " qualifier/start/stop list is " +                        "not represented in the scanColumnList." +                        "\n:required_cols_and_scan_list = " +                             required_cols_and_scan_list +                         "\n;required_cols = " + required_cols +

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -