📄 genericscancontroller.java
字号:
* the hashCode and equals method as appropriate for it's datatype. * <p> * It is expected that this call will be the first and only call made in * an openscan. Qualifiers and stop position of the openscan are applied * just as in a normal scan. This call is logically equivalent to the * caller performing the following: * * import java.util.Hashtable; * * hash_table = new Hashtable(); * * while (next()) * { * row = create_new_row(); * fetch(row); * if ((duplicate_value = * hash_table.put(row[key_column_number], row)) != null) * { * Vector row_vec; * * // inserted a duplicate * if ((duplicate_value instanceof vector)) * { * row_vec = (Vector) duplicate_value; * } * else * { * // allocate vector to hold duplicates * row_vec = new Vector(2); * * // insert original row into vector * row_vec.addElement(duplicate_value); * * // put the vector as the data rather than the row * hash_table.put(row[key_column_number], row_vec); * } * * // insert new row into vector * row_vec.addElement(row); * } * } * <p> * The columns of the row will be the standard columns returned as * part of a scan, as described by the validColumns - see openScan for * description. * RESOLVE - is this ok? or should I hard code somehow the row to * be the first column and the row location? * <p> * Currently it is only possible to hash on the first column in the * conglomerate, in the future we may change the interface to allow * hashing either on a different column or maybe on a combination of * columns. * <p> * No overflow to external storage is provided, so calling this routine * on a 1 gigabyte conglomerate will incur at least 1 gigabyte of memory * (probably failing with a java out of memory condition). If this * routine gets an out of memory condition, or if "max_rowcnt" is * exceeded then then the routine will give up, empty the Hashtable, * and return "false." * <p> * On exit from this routine, whether the fetchSet() succeeded or not * the scan is complete, it is positioned just the same as if the scan * had been drained by calling "next()" until it returns false (ie. * fetchNext() and next() calls will return false). * reopenScan() can be called to restart the scan. * <p> * * RESOLVE - until we get row counts what should we do for sizing the * the size, capasity, and load factor of the hash table. * For now it is up to the caller to create the Hashtable, * Access does not reset any parameters. * <p> * RESOLVE - I am not sure if access should be in charge of allocating * the new row objects. I know that I can do this in the * case of btree's, but I don't think I can do this in heaps. * Maybe this is solved by work to be done on the sort * interface. * * * @return boolean indicating that the fetch set succeeded. If it failed * Hashtable.clear() will be called leaving an empty * table. * * @param max_rowcnt The maximum number of rows to insert into the * Hash table. Pass in -1 if there is no maximum. * @param key_column_numbers The column numbers of the columns in the * scan result row to be the key to the Hashtable. * "0" is the first column in the scan result * row (which may be different than the first * column in the row in the table of the scan). * @param hash_table The java HashTable to load into. * * @exception StandardException Standard exception policy. **/ public void fetchSet( long max_rowcnt, int[] key_column_numbers, BackingStoreHashtable hash_table) throws StandardException { fetchRows( (DataValueDescriptor[][]) null, (RowLocation[]) null, hash_table, max_rowcnt, key_column_numbers); return; } /** 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 with against the same conglomerate, and the scan is reopened with the same "hold" and "forUpdate" parameters passed in the original openScan. The previous template row continues to be used. @param startKeyValue An indexable row which holds a (partial) key value which, in combination with the startSearchOperator, defines the starting position of the scan. If null, the starting position of the scan is the first row of the conglomerate. @param startSearchOperator an operator which defines how the startKeyValue is to be searched for. If startSearchOperator is ScanController.GE, the scan starts on the first row which is greater than or equal to the startKeyValue. If startSearchOperation is ScanController.GT, the scan starts on the first row whose key is greater than startKeyValue. The startSearchOperation parameter is ignored if the startKeyValue parameter is null. @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. @param stopKeyValue An indexable row which holds a (partial) key value which, in combination with the stopSearchOperator, defines the ending position of the scan. If null, the ending position of the scan is the last row of the conglomerate. @param stopSearchOperator an operator which defines how the stopKeyValue is used to determine the scan stopping position. If stopSearchOperation is ScanController.GE, the scan stops just before the first row which is greater than or equal to the stopKeyValue. If stopSearchOperation is ScanController.GT, the scan stops just before the first row whose key is greater than startKeyValue. The stopSearchOperation parameter is ignored if the stopKeyValue parameter is null. @exception StandardException Standard exception policy. **/ public void reopenScan( DataValueDescriptor[] startKeyValue, int startSearchOperator, Qualifier qualifier[][], DataValueDescriptor[] stopKeyValue, int stopSearchOperator) throws StandardException { if (SanityManager.DEBUG) { if (!open_conglom.getHold()) { SanityManager.ASSERT( !open_conglom.isClosed(), "GenericScanController.reopenScan() called on a non-held closed scan."); } } // initialize scan position parameters at beginning of scan this.scan_state = (!open_conglom.getHold() ? SCAN_INIT : SCAN_HOLD_INIT); scan_position.current_rh = null; } /** @see ScanController#replace **/ public boolean replace( DataValueDescriptor[] row, FormatableBitSet validColumns) throws StandardException { repositionScanForUpateOper(); boolean ret_val = scan_position.current_page.update( scan_position.current_rh, row, validColumns); scan_position.unlatch(); return(ret_val); } /** Returns true if the current position of the scan still qualifies under the set of qualifiers passed to the openScan(). When called this routine will reapply all qualifiers against the row currently positioned and return true if the row still qualifies. If the row has been deleted or no longer passes the qualifiers then this routine will return false. This case can come about if the current scan or another scan on the same table in the same transaction deleted the row or changed columns referenced by the qualifier after the next() call which positioned the scan at this row. Note that for comglomerates which don't support update, like btree's, there is no need to recheck the qualifiers. The results of a fetch() performed on a scan positioned on a deleted row are undefined. @exception StandardException Standard exception policy. **/ public boolean doesCurrentPositionQualify() throws StandardException { if (scan_state != SCAN_INPROGRESS) throw StandardException.newException( SQLState.AM_SCAN_NOT_POSITIONED); if (!open_conglom.latchPage(scan_position)) { return(false); } DataValueDescriptor row[] = open_conglom.getRuntimeMem().get_scratch_row(); // If fetchFromSlot returns null it either means the row is deleted, // or the qualifier evaluates to false. boolean ret_val = (scan_position.current_page.fetchFromSlot( scan_position.current_rh, scan_position.current_slot, row, init_fetchDesc, false) != null); scan_position.unlatch(); return(ret_val); } /** @see ScanController#fetch **/ public void fetch(DataValueDescriptor[] row) 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())); } // RESOLVE (mikem) - should this call apply the qualifiers again? RecordHandle rh = scan_position.current_page.fetchFromSlot( scan_position.current_rh, scan_position.current_slot, row, init_fetchDesc, false); scan_position.unlatch(); if (rh == null) { /* if (SanityManager.DEBUG) { if (isCurrentPositionDeleted()) SanityManager.THROWASSERT( "The record (" + open_conglom.getContainer().getId() + ", " + scan_position.current_rh.getPageNumber() + ", " + scan_position.current_rh.getId() + ") " + "being fetched is marked deleted on page.:\n"); } */ throw StandardException.newException( SQLState.AM_RECORD_NOT_FOUND, open_conglom.getContainer().getId(), new Long(scan_position.current_rh.getId())); } return; } /** Fetch the location of the current position in the scan. @see ScanController#fetchLocation @exception StandardException Standard exception policy. **/ public void fetchLocation(RowLocation templateLocation) throws StandardException { throw StandardException.newException( SQLState.BTREE_UNIMPLEMENTED_FEATURE); } /** * Return ScanInfo object which describes performance of scan. * <p> * Return ScanInfo object which contains information about the current * scan. * <p> * * @see ScanInfo * * @return The ScanInfo object which contains info about current scan. * * @exception StandardException Standard exception policy. **/ public ScanInfo getScanInfo() throws StandardException { throw StandardException.newException( SQLState.BTREE_UNIMPLEMENTED_FEATURE); } /** Returns true if the current position of the scan is at a deleted row. This case can come about if the current scan or another scan on the same table in the same transaction deleted the row after the next() call which positioned the scan at this row. The results of a fetch() performed on a scan positioned on a deleted row are undefined. @exception StandardException Standard exception policy. **/ public boolean isCurrentPositionDeleted() throws StandardException { if (scan_state != SCAN_INPROGRESS) throw StandardException.newException( SQLState.AM_SCAN_NOT_POSITIONED); if (!open_conglom.latchPage(scan_position)) { return(true); } boolean ret_val = scan_position.current_page.isDeletedAtSlot( scan_position.current_slot); scan_position.unlatch(); return(ret_val); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -