📄 genericscancontroller.java
字号:
"\n;init_scanColumnList = " + init_scanColumnList); } } } // Scan is fully initialized and ready to go. scan_state = SCAN_INIT; } /** * Reposition the scan upon entering the fetchRows loop. * <p> * Called upon entering fetchRows() while in the SCAN_INPROGRESS state. * Do work necessary to look at rows in the current page of the scan. * <p> * The default implementation uses a record handle to maintain a scan * position. It will get the latch again on the current * scan position and set the slot to the current record handle. * * @exception StandardException Standard exception policy. **/ protected void positionAtResumeScan( RowPosition pos) throws StandardException { if (SanityManager.DEBUG) { SanityManager.ASSERT( scan_position.current_rh != null, this.toString()); } // reposition the scan at the row just before the next one to return. // This routine handles the mess of repositioning if the row or the // page has disappeared. This can happen if a lock was not held on the // row while not holding the latch. open_conglom.latchPageAndRepositionScan(scan_position); } /** * Move the scan from SCAN_INIT to SCAN_INPROGRESS. * <p> * 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. * <p> * * @exception StandardException Standard exception policy. **/ protected void positionAtStartForForwardScan( RowPosition pos) throws StandardException { if (pos.current_rh == null) { // 1st positioning of scan (delayed from openScan). pos.current_page = open_conglom.getContainer().getFirstPage(); if (SanityManager.DEBUG) { SanityManager.ASSERT( pos.current_page.getPageNumber() == ContainerHandle.FIRST_PAGE_NUMBER); if (pos.current_page.recordCount() < 1) SanityManager.THROWASSERT( "record count = " + pos.current_page.recordCount()); } // set up for scan to continue at beginning of first page just // after first first control row on first page. pos.current_slot = Page.FIRST_SLOT_NUMBER; } else { // 1st positioning of scan following a reopenScanByRowLocation // reposition the scan at the row just before the next one to // return. This routine handles the mess of repositioning if the // row or the page has disappeared. This can happen if a lock was // not held on the row while not holding the latch. open_conglom.latchPageAndRepositionScan(pos); // set up for scan to at the specified record handle (position one // before it so that the loop increment and find it). pos.current_slot -= 1; } pos.current_rh = null; this.stat_numpages_visited = 1; this.scan_state = SCAN_INPROGRESS; } /** * Position scan to slot before first slot on next page. * <p> * @exception StandardException Standard exception policy. **/ protected void positionAtNextPage( RowPosition pos) throws StandardException { // The current_page can become null, in a rare multi-user case, where // all pages in the heap are deallocated, in the middle of the scan // loop, when no latches are held, and the scan is waiting on a lock. // In this case the lockPositionForRead code, has nowhere good to // position the scan, so it just sets the page to null and returns. if (pos.current_page != null) { // save current page number. long pageid = pos.current_page.getPageNumber(); // unlatch old page. pos.unlatch(); // latch page after current page number. pos.current_page = open_conglom.getContainer().getNextPage(pageid); // set up for scan to continue at beginning of this new page. pos.current_slot = Page.FIRST_SLOT_NUMBER - 1; } } /** * Do any necessary work to complete the scan. * * @exception StandardException Standard exception policy. **/ protected void positionAtDoneScan( RowPosition pos) throws StandardException { // Unlatch current page if any. pos.unlatch(); // unlock the previous row. if (scan_position.current_rh != null) { open_conglom.unlockPositionAfterRead(scan_position); scan_position.current_rh = null; } this.scan_state = SCAN_DONE; } public void reopenScanByRowLocation( RowLocation startRowLocation, Qualifier qualifier[][]) throws StandardException { throw StandardException.newException( SQLState.BTREE_UNIMPLEMENTED_FEATURE); } /************************************************************************** * Protected methods of This class: ************************************************************************** */ /** * Create object which represents the scan position. * <p> * Designed so that extending classes can override and allocate * implementation specific row position's. * * @exception StandardException Standard exception policy. **/ protected RowPosition allocateScanPosition() throws StandardException { return(new RowPosition()); } /** * Fetch the next N rows from the table. * <p> * Utility routine used by both fetchSet() and fetchNextGroup(). * * @exception StandardException Standard exception policy. **/ protected int fetchRows( DataValueDescriptor[][] row_array, RowLocation[] rowloc_array, BackingStoreHashtable hash_table, long max_rowcnt, int[] key_column_numbers) throws StandardException { int ret_row_count = 0; DataValueDescriptor[] fetch_row = null; if (max_rowcnt == -1) max_rowcnt = Long.MAX_VALUE; if (SanityManager.DEBUG) { if (row_array != null) { SanityManager.ASSERT(row_array[0] != null, "first array slot in fetchNextGroup() must be non-null."); SanityManager.ASSERT(hash_table == null); } else { SanityManager.ASSERT(hash_table != null); } } if (this.scan_state == SCAN_INPROGRESS) { positionAtResumeScan(scan_position); } else if (this.scan_state == SCAN_INIT) { positionAtStartForForwardScan(scan_position); } else if (this.scan_state == SCAN_HOLD_INPROGRESS) { open_conglom.reopen(); if (SanityManager.DEBUG) { SanityManager.ASSERT( scan_position.current_rh != null, this.toString()); } // reposition the scan at the row just before the next one to // return. // This routine handles the mess of repositioning if the row or // the page has disappeared. This can happen if a lock was not // held on the row while not holding the latch. open_conglom.latchPageAndRepositionScan(scan_position); this.scan_state = SCAN_INPROGRESS; } else if (this.scan_state == SCAN_HOLD_INIT) { open_conglom.reopen(); positionAtStartForForwardScan(scan_position); } else { if (SanityManager.DEBUG) SanityManager.ASSERT(this.scan_state == SCAN_DONE); return(0); } // At this point: // scan_position.current_page is latched. // scan_position.current_slot is the slot on scan_position.current_page // just before the "next" record this routine should process. // loop through successive pages and successive slots on those // pages. Stop when either the last page is reached // (scan_position.current_page will be null). // Along the way apply qualifiers to skip rows which don't qualify. while (scan_position.current_page != null) { while ((scan_position.current_slot + 1) < scan_position.current_page.recordCount()) { // unlock the previous row. if (scan_position.current_rh != null) { open_conglom.unlockPositionAfterRead(scan_position); } // Allocate a new row to read the row into. if (fetch_row == null) { if (hash_table == null) { // point at allocated row in array if one exists. if (row_array[ret_row_count] == null) { row_array[ret_row_count] = open_conglom.getRuntimeMem().get_row_for_export(); } fetch_row = row_array[ret_row_count]; } else { fetch_row = open_conglom.getRuntimeMem().get_row_for_export(); } } // move scan current position forward. scan_position.positionAtNextSlot(); // Lock the row. boolean lock_granted_while_latch_held = open_conglom.lockPositionForRead( scan_position, (RowPosition) null, true, true); if (!lock_granted_while_latch_held) { // if lock could not be granted while holding // latch, then the row may either be on the same page // or it may no longer exist, this implementation does not // handle rows which move to different pages. // // If the row moved on the same page then // lockPositionForRead() will have automatically updated // the scan_postion argument to point to it, and we // wil now have a latch and a lock on that row. // // If the row no longer exists then the // "moveForwardIfRowDisappears" argument makes this routine // find the "next" row in the heap and position on it. If // a valid row exists in the current page to position on, // then lockPositionForRead() will position on it, get // a lock on it, and return with a latch on the page. // Otherwise the routine will return with current_slot == -1 // and it is up to this routine to continue the scan as // normal at the top of the loop. if (scan_position.current_page == null) { // page has been unlatched and the scan is done, there // are no more pages. getNextPage() has been coded to // handle a null current_page. break; } else if (scan_position.current_slot == -1) { // This means that lockPositionForRead() had to // reposition the scan forward to a new page, because // the row the scan was locking was purged, when the // latch was released to wait on the lock. In this // case just jump back to the top of loop and continue // scan. if (SanityManager.DEBUG) { SanityManager.ASSERT( scan_position.current_rh == null); } continue; } } this.stat_numrows_visited++; // lockRowAtPosition set pos.current_rh as part of getting lock. if (SanityManager.DEBUG) { SanityManager.ASSERT(scan_position.current_rh != null); // make sure current_rh and current_slot are in sync if (scan_position.current_slot != scan_position.current_page.getSlotNumber( scan_position.current_rh)) { SanityManager.THROWASSERT( "current_slot = " + scan_position.current_slot + "current_rh = " + scan_position.current_rh + "current_rh.slot = " + scan_position.current_page.getSlotNumber( scan_position.current_rh)); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -