📄 genericscancontroller.java
字号:
// fetchFromSlot returns null if row does not qualify. scan_position.current_rh_qualified = (scan_position.current_page.fetchFromSlot( scan_position.current_rh, scan_position.current_slot, fetch_row, init_fetchDesc, false) != null); if (scan_position.current_rh_qualified) { // qualifying row. // scan_position.current_rh is save position of scan while // latch is not held. It currently points at the // scan_position.current_slot in search (while latch is // held). if (SanityManager.DEBUG) { // make sure current_rh and current_slot are in sync SanityManager.ASSERT( scan_position.current_slot == scan_position.current_page.getSlotNumber( scan_position.current_rh)); } // Found qualifying row. Done fetching rows for the group? ret_row_count++; stat_numrows_qualified++; if (hash_table == null) { if (rowloc_array != null) { // if requested return the associated row location. setRowLocationArray( rowloc_array, ret_row_count - 1, scan_position); } fetch_row = null; } else { if (hash_table.put(false, fetch_row)) { // The row was inserted into the hash table so we // need to create a new row next time through. fetch_row = null; } } if (max_rowcnt <= ret_row_count) { // exit fetch row loop and return to the client. scan_position.unlatch(); if (SanityManager.DEBUG) { SanityManager.ASSERT( scan_position.current_rh != null); } return(ret_row_count); } } } positionAtNextPage(scan_position); this.stat_numpages_visited++; } // Reached last page of scan. positionAtDoneScan(scan_position); // we need to decrement when we stop scan at the end of the table. this.stat_numpages_visited--; return(ret_row_count); } /** Reposition the current scan. This call is semantically the same as if the current scan had been closed and a openScan() had been called instead. The scan is reopened against the same conglomerate, and the scan is reopened with the same "scan column list", "hold" and "forUpdate" parameters passed in the original openScan. <p> The statistics gathered by the scan are not reset to 0 by a reopenScan(), rather they continue to accumulate. <p> Note that this operation is currently only supported on Heap conglomerates. Also note that order of rows within are heap are not guaranteed, so for instance positioning at a RowLocation in the "middle" of a heap, then inserting more data, then continuing the scan is not guaranteed to see the new rows - they may be put in the "beginning" of the heap. @param startRecordHandle An existing RecordHandle within the conglomerate, at which to position the start of the scan. The scan will begin at this location and continue forward until the end of the conglomerate. Positioning at a non-existent RowLocation (ie. an invalid one or one that had been deleted), will result in an exception being thrown when the first next operation is attempted. @param qualifier An array of qualifiers which, applied to each key, restrict the rows returned by the scan. Rows for which any one of the qualifiers returns false are not returned by the scan. If null, all rows are returned. @exception StandardException Standard exception policy. **/ protected void reopenScanByRecordHandle( RecordHandle startRecordHandle, Qualifier qualifier[][]) throws StandardException { // initialize scan position parameters at beginning of scan this.scan_state = (!open_conglom.getHold() ? SCAN_INIT : SCAN_HOLD_INIT); // position the scan at the row before the given record id, so that // the first "next" starts on the given row. scan_position.current_rh = startRecordHandle; } protected void setRowLocationArray( RowLocation[] rowloc_array, int index, RowPosition pos) throws StandardException { throw(StandardException.newException( SQLState.HEAP_UNIMPLEMENTED_FEATURE)); } /************************************************************************** * abstract protected Methods of This class: ************************************************************************** */ /************************************************************************** * Public Methods of This class: ************************************************************************** */ public void init( OpenConglomerate open_conglom, FormatableBitSet scanColumnList, DataValueDescriptor[] startKeyValue, int startSearchOperator, Qualifier qualifier[][], DataValueDescriptor[] stopKeyValue, int stopSearchOperator) throws StandardException { super.init(open_conglom); // RESOLVE (mikem) - move this into runtime_mem scan_position = allocateScanPosition(); // remember inputs init_scanColumnList = scanColumnList; positionAtInitScan( startKeyValue, startSearchOperator, qualifier, stopKeyValue, stopSearchOperator, scan_position); } public final int getNumPagesVisited() { return(stat_numpages_visited); } public final int getNumRowsVisited() { return(stat_numrows_visited); } public final int getNumRowsQualified() { return(stat_numrows_qualified); } public final FormatableBitSet getScanColumnList() { return(init_scanColumnList); } public final DataValueDescriptor[] getStartKeyValue() { return(init_startKeyValue); } public final int getStartSearchOperator() { return(init_startSearchOperator); } public final DataValueDescriptor[] getStopKeyValue() { return(init_stopKeyValue); } public final int getStopSearchOperator() { return(init_stopSearchOperator); } public final Qualifier[][] getQualifier() { return(init_qualifier); } public final int getScanState() { return(scan_state); } public final void setScanState(int state) { scan_state = state; } public final RowPosition getScanPosition() { return(scan_position); } public final void setScanPosition(RowPosition pos) { scan_position = pos; } /************************************************************************** * Public Methods implementing ScanController: ************************************************************************** */ private void closeScan() throws StandardException { super.close(); // If we are closed due to catching an error in the middle of init, // xact_manager may not be set yet. if (open_conglom.getXactMgr() != null) open_conglom.getXactMgr().closeMe(this); // help the garbage collector. this.init_qualifier = null; init_scanColumnList = null; init_startKeyValue = null; init_stopKeyValue = null; } public void close() throws StandardException { // Finish the scan - this may release locks if read committed and scan // still holds some locks, and close comes before scan.next() returned // that scan was done. positionAtDoneScan(scan_position); closeScan(); } public boolean closeForEndTransaction( boolean closeHeldScan) throws StandardException { if ((!open_conglom.getHold()) || closeHeldScan) { // close the scan as part of the commit/abort this.scan_state = SCAN_DONE; closeScan(); return(true); } else { super.close(); // allow the scan to continue after the commit. // locks and latches will be released as part of the commit, so // no need to release them by hand. if (this.scan_state == SCAN_INPROGRESS) this.scan_state = SCAN_HOLD_INPROGRESS; else if (this.scan_state == SCAN_INIT) this.scan_state = SCAN_HOLD_INIT; return(false); } } /** @see ScanController#delete **/ public boolean delete() throws StandardException { repositionScanForUpateOper(); boolean ret_val = true; // RESOLVE (mikem) - RECID - performance could be better if we did not // have to call isDeletedAtSlot(). // RESOLVE (mikem) - share code below with conglomerateController. if (scan_position.current_page.isDeletedAtSlot( scan_position.current_slot)) { ret_val = false; } else { // Delete the row scan_position.current_page.deleteAtSlot( scan_position.current_slot, true, (LogicalUndo) null); if (scan_position.current_page.nonDeletedRecordCount() == 0) { queueDeletePostCommitWork(scan_position); } } scan_position.unlatch(); return(ret_val); } /** * A call to allow client to indicate that current row does not qualify. * <p> * Indicates to the ScanController that the current row does not * qualify for the scan. If the isolation level of the scan allows, * this may result in the scan releasing the lock on this row. * <p> * Note that some scan implimentations may not support releasing locks on * non-qualifying rows, or may delay releasing the lock until sometime * later in the scan (ie. it may be necessary to keep the lock until * either the scan is repositioned on the next row or page). * <p> * This call should only be made while the scan is positioned on a current * valid row. * RESOLVE (mikem-05/29/98) - Implement this when we support levels of * concurrency less than serializable. * * @exception StandardException Standard exception policy. **/ public void didNotQualify() throws StandardException { } /** * Insert all rows that qualify for the current scan into the input * Hash table. * <p> * This routine scans executes the entire scan as described in the * openScan call. For every qualifying unique row value an entry is * placed into the HashTable. For unique row values the entry in the * Hashtable has a key value of the object stored in * row[key_column_number], and the value of the data is row. For row * values with duplicates, the key value is also row[key_column_number], * but the value of the data is a Vector of * rows. The caller will have to call "instanceof" on the data value * object if duplicates are expected, to determine if the data value * of the Hashtable entry is a row or is a Vector of rows. * <p> * Note, that for this routine to work efficiently the caller must * ensure that the object in row[key_column_number] implements
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -