📄 btreeforwardscan.java
字号:
while ((pos.current_slot + 1) < pos.current_leaf.page.recordCount()) { // System.out.println( // "2 of fetchSet loop, ret_row_count = " + ret_row_count + // "fetch_row = " + fetch_row + // "hash_table = " + hash_table); // unlock the previous row if doing read. if (pos.current_rh != null) { this.getLockingPolicy().unlockScanRecordAfterRead( pos, init_forUpdate); // current_rh is used to track which row we need to unlock, // at this point no row needs to be unlocked. pos.current_rh = null; } // 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] = runtime_mem.get_row_for_export(); } fetch_row = row_array[ret_row_count]; } else { // get a brand new row. fetch_row = runtime_mem.get_row_for_export(); } } // move scan current position forward. pos.current_slot++; this.stat_numrows_visited++; rh = pos.current_leaf.page.fetchFromSlot( (RecordHandle) null, pos.current_slot, fetch_row, init_fetchDesc, true); pos.current_rh_qualified = true; // See if this is the stop row. if (init_stopKeyValue != null) { // See if current row is the >= the stopKeyValue. // // ret > 0: key is greater than row on page. // ret == 0: key is exactly the row on page if full key, // or partial match if partial key. // ret < 0: key is less than row on page. // int ret = ControlRow.CompareIndexRowToKey( fetch_row, init_stopKeyValue, fetch_row.length, 0, this.getConglomerate().ascDescInfo); if ((ret == 0) && (init_stopSearchOperator == ScanController.GE)) { // if (partial) matched and stop is GE, end the scan. ret = 1; } if (ret > 0) { // This is the first non-qualifying row. We're done. pos.current_leaf.release(); pos.current_leaf = null; positionAtDoneScan(pos); return(ret_row_count); } } // Only lock rows that are < the stopKeyValue. No need to // requalify against stop position after losing the latch // as the only change that could have happened is that the // row was marked deleted - the key value cannot change. boolean latch_released = !this.getLockingPolicy().lockScanRow( this, this.getConglomerate(), pos, false, init_lock_fetch_desc, pos.current_lock_template, pos.current_lock_row_loc, false, init_forUpdate, lock_operation); // special test to see if latch release code works if (SanityManager.DEBUG) { latch_released = test_errors( this, "BTreeScan_fetchNextGroup", false, this.getLockingPolicy(), pos.current_leaf, latch_released); } // At this point we have successfully locked this record, so // remember the record handle so that it can be unlocked if // necessary. If the above lock deadlocks, we will not try // to unlock a lock we never got in close(), because current_rh // is null until after the lock is granted. pos.current_rh = rh; 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 (this.getConglomerate().isUnique()) { // Handle row location changing since lock request was // initiated. // In unique indexes, there is one case where an index // row can have it's data lock key change (this usually // cannot happen because only inserts and deletes are // allowed - no updates). This case is an insert of a // key, that exactly matches a committed deleted row, // in a unique index. In that case the code updates // the RowLocation column and flips the deleted bit to // mark the row valid. The problem is that if this // happens while we are waiting on a lock on the old // RowLocation then when we wake up we have the wrong // lock, and the row location we fetched earlier in // this loop is invalid. while (latch_released) { if (!reposition(pos, false)) { if (SanityManager.DEBUG) { // can't fail while with scan lock SanityManager.THROWASSERT( "can not fail holding scan lock."); } // reposition will set pos.current_leaf to // null, if it returns false so if the this // ever does fail in delivered code, expect // a null pointer exception on the next line, // trying to call fetchFromSlot(). } pos.current_leaf.page.fetchFromSlot( (RecordHandle) null, pos.current_slot, fetch_row, init_fetchDesc, true); latch_released = !this.getLockingPolicy().lockScanRow( this, this.getConglomerate(), pos, false, init_lock_fetch_desc, pos.current_lock_template, pos.current_lock_row_loc, false, init_forUpdate, lock_operation); } } else { if (!reposition(pos, false)) { if (SanityManager.DEBUG) { // can't fail while with scan lock SanityManager.THROWASSERT( "can not fail holding scan lock."); } // reposition will set pos.current_leaf to // null, if it returns false so if the this // ever does fail in delivered code, expect // a null pointer exception on the next line, // trying to call isDeletedAtSlot(). } } } if (pos.current_leaf.page.isDeletedAtSlot(pos.current_slot)) { this.stat_numdeleted_rows_visited++; pos.current_rh_qualified = false; } else if (init_qualifier != null) { // Apply qualifiers if there are any. pos.current_rh_qualified = this.process_qualifier(fetch_row); } if (pos.current_rh_qualified) { // qualifying row. Save position, release latch and return. // this.current_rh is save position of scan while latch is // not held. It currently points at the current_slot in // search (while latch is held). if (SanityManager.DEBUG) { SanityManager.ASSERT( pos.current_leaf.page.getSlotNumber(pos.current_rh) == pos.current_slot); } // Found qualifying row. Are we done fetching rows for the // group? ret_row_count++; stat_numrows_qualified++; if (hash_table != null) { if (hash_table.put(false, fetch_row)) fetch_row = null; } else { fetch_row = null; } if (max_rowcnt <= ret_row_count) { // current_slot is invalid after releasing latch pos.current_slot = Page.INVALID_SLOT_NUMBER; // exit fetch row loop and return to the client. pos.current_leaf.release(); pos.current_leaf = null; return(ret_row_count); } } } // Move position of the scan to slot 0 of the next page. If there // is no next page current_page will be null. positionAtNextPage(pos); this.stat_numpages_visited++; } // Reached last leaf of tree. positionAtDoneScan(pos); // we need to decrement when we stop scan at the end of the table. this.stat_numpages_visited--; return(ret_row_count); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -