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

📄 btreescan.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
     *     *     * @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	{        // RESOLVE (mikem) - performance - we need to do a buffer manager        // get for every row returned from the scan.  It may be better to        // allow a reference to the page with no latch (ie. a fixed bit).        if (this.scan_state != SCAN_INPROGRESS)        {            throw StandardException.newException(                SQLState.BTREE_SCAN_NOT_POSITIONED,                 new Integer(this.scan_state));        }        // Either current_rh or positionKey is valid - the other is null.        if (SanityManager.DEBUG)        {			if ((pos.current_rh == null) != (pos.current_positionKey != null))            	SanityManager.THROWASSERT(                	"pos.current_rh  = (" + pos.current_rh + "), " +                	"pos.current_positionKey = (" +                     pos.current_positionKey + ").");        }        if (!((pos.current_rh == null) == (pos.current_positionKey != null)))        {            throw StandardException.newException(                    SQLState.BTREE_SCAN_INTERNAL_ERROR,                     new Boolean(pos.current_rh == null),                     new Boolean(pos.current_positionKey == null));        }        if (pos.current_positionKey == null)        {            // Reposition to remembered spot on page.            if (SanityManager.DEBUG)                SanityManager.ASSERT(pos.current_scan_pageno != 0);            pos.current_leaf = (LeafControlRow)                ControlRow.Get(this, pos.current_rh.getPageNumber());            pos.current_slot =                pos.current_leaf.page.getSlotNumber(pos.current_rh);        }        else        {            // RESOLVE (mikem) - not sure but someday in the future this            // assert may not be true, but for now we always release the             // scan lock when we save the row away as the current position.            if (SanityManager.DEBUG)                SanityManager.ASSERT(pos.current_scan_pageno == 0);            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);            // latch/lock loop, continue until you can get scan lock on page            // while holding page latched without waiting.            boolean latch_released;            do            {                pos.current_leaf = (LeafControlRow)                    ControlRow.Get(this, BTree.ROOTPAGEID).search(sp);                if (sp.resultExact || missing_row_for_key_ok)                {                    // RESOLVE (mikem) - we could have a scan which always                     // maintained it's position by key value, or we could                     // optimize and delay this lock until we were about to                     // give up the latch.  But it is VERY likely we will get                     // the lock since we have the latch on the page.                    //                    // In order to be successfully positioned we must get the                     // scan lock again.                    latch_released =                         !this.getLockingPolicy().lockScan(                            pos.current_leaf,                             (LeafControlRow) null, // no other latch currently                            false /* not for update */,                            ConglomerateController.LOCK_READ); // read lock on scan position                    // TESTING CODE:                    if (SanityManager.DEBUG)                    {                        latch_released =                             test_errors(                                this,                                "BTreeScan_reposition", true,                                 this.getLockingPolicy(),                                pos.current_leaf, latch_released);                    }                }                else                {                    // Did not find key to exactly position on.                    pos.current_leaf.release();                    pos.current_leaf = null;                    return(false);                }            } while (latch_released);            pos.current_scan_pageno = pos.current_leaf.page.getPageNumber();            pos.current_slot        = sp.resultSlot;            pos.current_positionKey = null;        }        return(true);	}	/*	** Public Methods of BTreeScan	*/	/**	Initialize the scan for use.	<p>	Any changes to this method may have to be reflected in close as well.    <p>    The btree init opens the container (super.init), and stores away the    state of the qualifiers.  The actual searching for the first position    is delayed until the first next() call.	@exception  StandardException  Standard exception policy.	**/	public void init(    TransactionManager              xact_manager,    Transaction                     rawtran,    boolean                         hold,    int                             open_mode,    int                             lock_level,    BTreeLockingPolicy              btree_locking_policy,    FormatableBitSet                         scanColumnList,    DataValueDescriptor[]		    startKeyValue,    int                             startSearchOperator,    Qualifier                       qualifier[][],    DataValueDescriptor[]		    stopKeyValue,    int                             stopSearchOperator,    BTree                           conglomerate,    LogicalUndo                     undo,    StaticCompiledOpenConglomInfo   static_info,    DynamicCompiledOpenConglomInfo  dynamic_info)        throws StandardException	{		super.init(            xact_manager, xact_manager, (ContainerHandle) null, rawtran,            hold,            open_mode, lock_level, btree_locking_policy,             conglomerate, undo, dynamic_info);        this.init_rawtran               = rawtran;        this.init_forUpdate             =             ((open_mode & ContainerHandle.MODE_FORUPDATE) ==                  ContainerHandle.MODE_FORUPDATE);		// Keep track of whether this scan should use update locks.		this.init_useUpdateLocks =             ((open_mode &                ContainerHandle.MODE_USE_UPDATE_LOCKS) != 0);		this.init_hold                  = hold;		this.init_template              = runtime_mem.get_template();        this.init_scanColumnList        = scanColumnList;        this.init_lock_fetch_desc        =             RowUtil.getFetchDescriptorConstant(init_template.length - 1);        if (SanityManager.DEBUG)        {            SanityManager.ASSERT(                init_lock_fetch_desc.getMaxFetchColumnId() ==                     (init_template.length - 1));            SanityManager.ASSERT(                (init_lock_fetch_desc.getValidColumnsArray())[init_template.length - 1] == 1);         }        // note that we don't process qualifiers in btree fetch's        this.init_fetchDesc             =             new FetchDescriptor(                init_template.length, init_scanColumnList,(Qualifier[][]) null);        initScanParams(             startKeyValue, startSearchOperator,             qualifier, stopKeyValue, stopSearchOperator);                if (SanityManager.DEBUG)        {            // RESOLVE - (mikem) we should we require a template, need to             // clean up some of the old tests which did not provide one?            if (init_template != null)            {                SanityManager.ASSERT(                    TemplateRow.checkColumnTypes(                        this.getConglomerate().format_ids, init_template));            }        }        // System.out.println("initializing scan:" + this);        // initialize default locking operation for the scan.        this.lock_operation =             (init_forUpdate ?                 ConglomerateController.LOCK_UPD :                 ConglomerateController.LOCK_READ);        if (init_useUpdateLocks)            this.lock_operation |= ConglomerateController.LOCK_UPDATE_LOCKS;        // System.out.println("Btree scan: " + this);	}	/*	** Methods of ScanController	*/    /**    Close the scan.    **/    public void close()        throws StandardException	{        // Scan is closed, make sure no access to any state variables        positionAtDoneScanFromClose(scan_position);		super.close();        // null out so that these object's can get GC'd earlier.        this.init_rawtran       = null;        this.init_template      = null;        this.init_startKeyValue = null;        this.init_qualifier     = null;        this.init_stopKeyValue  = null;        this.getXactMgr().closeMe(this);	}    /**    Delete the row at the current position of the scan.	@see ScanController#delete	@exception  StandardException  Standard exception policy.    **/    public boolean delete()		throws StandardException	{        boolean     ret_val      = false;        if (scan_state != SCAN_INPROGRESS)            throw StandardException.newException(                SQLState.AM_SCAN_NOT_POSITIONED);        if (SanityManager.DEBUG)        {            SanityManager.ASSERT(this.container != null,                "BTreeScan.delete() called on a closed scan.");            SanityManager.ASSERT(init_forUpdate);        }        try        {            // Get current page of scan, with latch.            if (!reposition(scan_position, false))            {                throw StandardException.newException(                        SQLState.AM_RECORD_NOT_FOUND,                        new Long(err_containerid),                        new Long(scan_position.current_rh.getId()));            }            if (init_useUpdateLocks)            {                // RESOLVE (mikem) - I don't think lockScanRow() is the right                // thing to call.                // if we are doing update locking, then we got an U lock on                // this row when the scan positioned on it, but now that we                // are doing a delete on the current position we need to upgrade                // the lock to X.                boolean latch_released =                    !this.getLockingPolicy().lockScanRow(                        this, this.getConglomerate(), scan_position,                        false,                         init_lock_fetch_desc,                        scan_position.current_lock_template,                        scan_position.current_lock_row_loc,                        false, init_forUpdate, lock_operation);                if (latch_released)                {                    // lost latch on page in order to wait for row lock.                    // Because we have scan lock on page, we need only                    // call reposition() which will use the saved record                    // handle to reposition to the same spot on the page.                    // We don't have to search the                    // tree again, as we have the a scan lock on the page                    // which means the current_rh is valid to reposition on.                    if (reposition(scan_position, false))                    {                        throw StandardException.newException(                                SQLState.AM_RECORD_NOT_FOUND,                                new Long(err_containerid),                                new Long(scan_position.current_rh.getId()));                    }                }            }            // Do a fetch just to get the RecordHandle for the delete call,            // don't fetch any columns.            RecordHandle delete_rh =                 scan_position.current_leaf.page.fetchFromSlot(                    (RecordHandle) null, scan_position.current_slot,                     RowUtil.EMPTY_ROW, (FetchDescriptor) null, true);

⌨️ 快捷键说明

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