org.apache.derby.impl.store.access.btree
Class BTreeScan

java.lang.Object
  extended byorg.apache.derby.impl.store.access.btree.OpenBTree
      extended byorg.apache.derby.impl.store.access.btree.BTreeScan
All Implemented Interfaces:
GenericScanController, GroupFetchScanController, RowCountable, ScanController, ScanManager
Direct Known Subclasses:
BTreeForwardScan, BTreeMaxScan

public abstract class BTreeScan
extends OpenBTree
implements ScanManager

A b-tree scan controller corresponds to an instance of an open b-tree scan.

Concurrency Notes<\B>

The concurrency rules are derived from OpenBTree.

See Also:
OpenBTree

Field Summary
protected  DataValueDescriptor[][] fetchNext_one_slot_array
          A 1 element array to turn fetchNext and fetch calls into fetchNextGroup calls.
protected  FetchDescriptor init_fetchDesc
          The fetch descriptor which describes the row to be returned by the scan.
protected  boolean init_forUpdate
           
protected  boolean init_hold
           
protected  FetchDescriptor init_lock_fetch_desc
          A constant FetchDescriptor which describes the position of the RowLocation field within the btree, currently always the last column).
protected  Qualifier[][] init_qualifier
           
protected  Transaction init_rawtran
          init_startKeyValue, init_qualifier, and init_stopKeyValue all are used to store * references to the values passed in when ScanController.init() is called.
protected  FormatableBitSet init_scanColumnList
           
protected  DataValueDescriptor[] init_startKeyValue
           
protected  int init_startSearchOperator
           
protected  DataValueDescriptor[] init_stopKeyValue
           
protected  int init_stopSearchOperator
           
protected  DataValueDescriptor[] init_template
           
protected  boolean init_useUpdateLocks
          Whether the scan should requests UPDATE locks which then will be converted to X locks when the actual operation is performed.
protected  int lock_operation
          What kind of row locks to get during the scan.
protected static int SCAN_DONE
           
protected static int SCAN_HOLD_INIT
           
protected static int SCAN_HOLD_INPROGRESS
           
protected static int SCAN_INIT
           
protected static int SCAN_INPROGRESS
           
(package private)  BTreeRowPosition scan_position
           
protected  int scan_state
          Delay positioning the table at the start position until the first next() call.
protected  int stat_numdeleted_rows_visited
           
protected  int stat_numpages_visited
          Performance counters ...
protected  int stat_numrows_qualified
           
protected  int stat_numrows_visited
           
 
Fields inherited from class org.apache.derby.impl.store.access.btree.OpenBTree
btree_undo, container, err_containerid, init_lock_level, init_open_user_scans, runtime_mem
 
Fields inherited from interface org.apache.derby.iapi.store.access.ScanController
GE, GT, NA
 
Constructor Summary
BTreeScan()
           
 
Method Summary
 void close()
          Close the scan.
 boolean closeForEndTransaction(boolean closeHeldScan)
          Close the scan, a commit or abort is about to happen.
 boolean delete()
          Delete the row at the current position of the scan.
 void didNotQualify()
          A call to allow client to indicate that current row does not qualify.
 boolean doesCurrentPositionQualify()
          Returns true if the current position of the scan still qualifies under the set of qualifiers passed to the openScan().
 void fetch(DataValueDescriptor[] row)
          Fetch the row at the current position of the Scan.
 void fetchLocation(RowLocation templateLocation)
          Fetch the location of the current position in the scan.
 boolean fetchNext(DataValueDescriptor[] row)
          Fetch the row at the next position of the Scan.
 int fetchNextGroup(DataValueDescriptor[][] row_array, RowLocation[] rowloc_array)
          Fetch the next N rows from the table.
 int fetchNextGroup(DataValueDescriptor[][] row_array, RowLocation[] old_rowloc_array, RowLocation[] new_rowloc_array)
           
protected abstract  int fetchRows(BTreeRowPosition pos, DataValueDescriptor[][] row_array, RowLocation[] rowloc_array, BackingStoreHashtable hash_table, long max_rowcnt, int[] key_column_numbers)
          Fetch the next N rows from the table.
 void fetchSet(long max_rowcnt, int[] key_column_numbers, BackingStoreHashtable hash_table)
          Insert all rows that qualify for the current scan into the input Hash table.
 RecordHandle getCurrentRecordHandleForDebugging()
           
 ScanInfo getScanInfo()
          Return ScanInfo object which describes performance of scan.
 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)
          Initialize the scan for use.
private  void initScanParams(DataValueDescriptor[] startKeyValue, int startSearchOperator, Qualifier[][] qualifier, DataValueDescriptor[] stopKeyValue, int stopSearchOperator)
          Shared initialization code between init() and reopenScan().
 boolean isCurrentPositionDeleted()
          Returns true if the current position of the scan is at a deleted row.
 boolean isKeyed()
          Return whether this is a keyed conglomerate.
 RowLocation newRowLocationTemplate()
          Return a row location object of the correct type to be used in calls to fetchLocation.
 boolean next()
          Move to the next position in the scan.
protected  void positionAtDoneScan(BTreeRowPosition pos)
          Do work necessary to close a scan.
protected  void positionAtDoneScanFromClose(BTreeRowPosition pos)
          Do any necessary work to complete the scan.
protected  void positionAtNextPage(BTreeRowPosition pos)
          Position scan to 0 slot on next page.
protected  void positionAtStartForBackwardScan(BTreeRowPosition pos)
          Position scan at "start" position for a backward scan.
protected  void positionAtStartForForwardScan(BTreeRowPosition pos)
          Position scan at "start" position for a forward scan.
(package private) abstract  void positionAtStartPosition(BTreeRowPosition pos)
          Position scan at "start" position.
protected  boolean process_qualifier(DataValueDescriptor[] row)
          process_qualifier - Determine if a row meets all qualifier conditions.
 void reopenScan(DataValueDescriptor[] startKeyValue, int startSearchOperator, Qualifier[][] qualifier, DataValueDescriptor[] stopKeyValue, int stopSearchOperator)
          Reposition the current scan.
 void reopenScanByRowLocation(RowLocation startRowLocation, Qualifier[][] qualifier)
          Reposition the current scan.
 boolean replace(DataValueDescriptor[] row, FormatableBitSet validColumns)
          Replace the entire row at the current position of the scan.
protected  boolean reposition(BTreeRowPosition pos, boolean missing_row_for_key_ok)
          Reposition the scan leaving and reentering the access layer.
private  void savePosition()
          Do work necessary to maintain the current position in the scan.
 void savePosition(Conglomerate conglom, Page page)
          Do work necessary to maintain the current position in the scan.
 java.lang.String toString()
           
 
Methods inherited from class org.apache.derby.impl.store.access.btree.OpenBTree
checkConsistency, debugConglomerate, getColumnSortOrderInfo, getConglomerate, getContainer, getContainerHandle, getEstimatedRowCount, getHeight, getHold, getLockingPolicy, getLockLevel, getOpenMode, getRawTran, getRuntimeMem, getSpaceInfo, getXactMgr, init, isClosed, isIndexableRowConsistent, isTableLocked, makeRecordHandle, reopen, setEstimatedRowCount, setLockingPolicy, test_errors
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface org.apache.derby.iapi.store.access.GenericScanController
isTableLocked
 
Methods inherited from interface org.apache.derby.iapi.store.access.RowCountable
getEstimatedRowCount, setEstimatedRowCount
 

Field Detail

init_rawtran

protected Transaction init_rawtran
init_startKeyValue, init_qualifier, and init_stopKeyValue all are used to store * references to the values passed in when ScanController.init() is called. It is assumed that these are not altered by the client while the scan is active.


init_forUpdate

protected boolean init_forUpdate

init_scanColumnList

protected FormatableBitSet init_scanColumnList

init_template

protected DataValueDescriptor[] init_template

init_startKeyValue

protected DataValueDescriptor[] init_startKeyValue

init_startSearchOperator

protected int init_startSearchOperator

init_qualifier

protected Qualifier[][] init_qualifier

init_stopKeyValue

protected DataValueDescriptor[] init_stopKeyValue

init_stopSearchOperator

protected int init_stopSearchOperator

init_hold

protected boolean init_hold

init_fetchDesc

protected FetchDescriptor init_fetchDesc
The fetch descriptor which describes the row to be returned by the scan.


init_lock_fetch_desc

protected FetchDescriptor init_lock_fetch_desc
A constant FetchDescriptor which describes the position of the RowLocation field within the btree, currently always the last column). Used by lock/unlock to fetch the RowLocation. Only needs to be allocated once per scan.


scan_position

BTreeRowPosition scan_position

init_useUpdateLocks

protected boolean init_useUpdateLocks
Whether the scan should requests UPDATE locks which then will be converted to X locks when the actual operation is performed.


SCAN_INIT

protected static final int SCAN_INIT
See Also:
Constant Field Values

SCAN_INPROGRESS

protected static final int SCAN_INPROGRESS
See Also:
Constant Field Values

SCAN_DONE

protected static final int SCAN_DONE
See Also:
Constant Field Values

SCAN_HOLD_INIT

protected static final int SCAN_HOLD_INIT
See Also:
Constant Field Values

SCAN_HOLD_INPROGRESS

protected static final int SCAN_HOLD_INPROGRESS
See Also:
Constant Field Values

scan_state

protected int scan_state
Delay positioning the table at the start position until the first next() call. The initial position is done in positionAtStartPosition().


stat_numpages_visited

protected int stat_numpages_visited
Performance counters ...


stat_numrows_visited

protected int stat_numrows_visited

stat_numrows_qualified

protected int stat_numrows_qualified

stat_numdeleted_rows_visited

protected int stat_numdeleted_rows_visited

lock_operation

protected int lock_operation
What kind of row locks to get during the scan.


fetchNext_one_slot_array

protected DataValueDescriptor[][] fetchNext_one_slot_array
A 1 element array to turn fetchNext and fetch calls into fetchNextGroup calls.

Constructor Detail

BTreeScan

public BTreeScan()
Method Detail

fetchRows

protected abstract int fetchRows(BTreeRowPosition pos,
                                 DataValueDescriptor[][] row_array,
                                 RowLocation[] rowloc_array,
                                 BackingStoreHashtable hash_table,
                                 long max_rowcnt,
                                 int[] key_column_numbers)
                          throws StandardException
Fetch the next N rows from the table.

Utility routine used by both fetchSet() and fetchNextGroup().

Throws:
StandardException - Standard exception policy.

initScanParams

private void initScanParams(DataValueDescriptor[] startKeyValue,
                            int startSearchOperator,
                            Qualifier[][] qualifier,
                            DataValueDescriptor[] stopKeyValue,
                            int stopSearchOperator)
                     throws StandardException
Shared initialization code between init() and reopenScan().

Basically save away input parameters describing qualifications for the scan, and do some error checking.

Throws:
StandardException - Standard exception policy.

positionAtStartForForwardScan

protected void positionAtStartForForwardScan(BTreeRowPosition pos)
                                      throws StandardException
Position scan at "start" position for a forward scan.

Positions the scan to the slot just before the first record to be returned from the scan. Returns the start page latched, and sets "current_slot" to the slot number.

Returns:
The leaf on which scan is positioned.
Throws:
StandardException - Standard exception policy.

positionAtStartForBackwardScan

protected void positionAtStartForBackwardScan(BTreeRowPosition pos)
                                       throws StandardException
Position scan at "start" position for a backward scan.

Positions the scan to the slot just after the first record to be returned from the backward scan. Returns the start page latched, and sets "current_slot" to the slot number just right of the first slot to return.

Returns:
The leaf page containing the start position, or null if no start position is found.
Throws:
StandardException - Standard exception policy.

positionAtNextPage

protected void positionAtNextPage(BTreeRowPosition pos)
                           throws StandardException
Position scan to 0 slot on next page.

Position to next page, keeping latch on previous page until we have latch on next page. This routine releases the latch on current_page once it has successfully gotten both the latch on the next page and the scan lock on the next page.

Parameters:
pos - current row position of the scan.
Returns:
The next leaf page, null if scan is done.
Throws:
StandardException - Standard exception policy.

positionAtStartPosition

abstract void positionAtStartPosition(BTreeRowPosition pos)
                               throws StandardException
Position scan at "start" position.

Positions the scan to the slot just before the first record to be returned from the scan. Returns the start page latched, and sets "current_slot" to the slot number.

Throws:
StandardException - Standard exception policy.

positionAtDoneScanFromClose

protected void positionAtDoneScanFromClose(BTreeRowPosition pos)
                                    throws StandardException
Do any necessary work to complete the scan.

Parameters:
pos - current row position of the scan.
Throws:
StandardException - Standard exception policy.

positionAtDoneScan

protected void positionAtDoneScan(BTreeRowPosition pos)
                           throws StandardException
Do work necessary to close a scan.

This routine can only be called "inline" from other btree routines, as it counts on the state of the pos to be correct.

Closing a scan from close() must handle long jumps from exceptions where the state of pos may not be correct. The easiest case is a lock timeout which has caused us not to have a latch on a page, but pos still thinks there is a latch. This is the easiest but other exceptions can also caused the same state at close() time.

Throws:
StandardException

process_qualifier

protected boolean process_qualifier(DataValueDescriptor[] row)
                             throws StandardException
process_qualifier - Determine if a row meets all qualifier conditions.

Check all qualifiers in the qualifier array against row. Return true if all compares specified by the qualifier array return true, else return false.

It is up to caller to make sure qualifier list is non-null.

Parameters:
row - The row with the same partial column list as the row returned by the current scan.
Throws:
StandardException - Standard exception policy.

reposition

protected boolean reposition(BTreeRowPosition pos,
                             boolean missing_row_for_key_ok)
                      throws StandardException
Reposition the scan leaving and reentering the access layer.

When a scan leaves access it saves the RecordHandle of the record on the page. There are 2 cases to consider when trying to reposition the scan when re-entering access: o ROW has not moved off the page. If the row has not moved then the RecordHandle we have saved away is valid, and we just call RawStore to reposition on that RecordHandle (RawStore takes care of the row moving within the page). o ROW has moved off the page. This can only happen in the case of a btree split. In that case the splitter will have caused all scans positioned on this page within the same transaction to save a copy of the row that the scan was positioned on. Then to reposition the scan it is necessary to research the tree from the top using the copy of the row. If the scan has saved it's position by key (and thus has given up the scan lock on the page), there are a few cases where it is possible that the key no longer exists in the table. In the case of a scan held open across commit it is easy to imagine that the row the scan was positioned on could be deleted and subsequently purged from the table all before the scan resumes. Also in the case of read uncommitted the scan holds no lock on the current row, so it could be purged - in the following scenario for instance: read uncommitted transaction 1 opens scan and positions on row (1,2), transaction 2 deletes (1,2) and commits, transaction 1 inserts (1,3) which goes to same page as (1,2) and is going to cause a split, transaction 1 saves scan position as key, gives up scan lock and then purges row (1, 2), when transaction 1 resumes scan (1, 2) no longer exists. missing_row_for_key_ok parameter is added as a sanity check to make sure it ok that repositioning does not go to same row that we were repositioned on.

Parameters:
pos - position to set the scan to.
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")
Returns:
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.
Throws:
StandardException - Standard exception policy.

init

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
Initialize the scan for use.

Any changes to this method may have to be reflected in close as well.

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.

Throws:
StandardException - Standard exception policy.

close

public void close()
           throws StandardException
Close the scan.

Specified by:
close in interface GenericScanController
Overrides:
close in class OpenBTree
Throws:
StandardException

delete

public boolean delete()
               throws StandardException
Delete the row at the current position of the scan.

Specified by:
delete in interface ScanController
Returns:
true if the delete was successful, false if the current position is no longer valid (ie. if it was already deleted).
Throws:
StandardException - Standard exception policy.
See Also:
ScanController.delete()

didNotQualify

public void didNotQualify()
                   throws StandardException
A call to allow client to indicate that current row does not qualify.

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.

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).

This call should only be made while the scan is positioned on a current valid row.

Specified by:
didNotQualify in interface ScanController
Throws:
StandardException - Standard exception policy.

doesCurrentPositionQualify

public boolean doesCurrentPositionQualify()
                                   throws StandardException
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.

Specified by:
doesCurrentPositionQualify in interface ScanController
Throws:
StandardException - Standard exception policy.

fetch

public void fetch(DataValueDescriptor[] row)
           throws StandardException
Fetch the row at the current position of the Scan.

Specified by:
fetch in interface ScanController
Parameters:
row - The row into which the value of the current position in the scan is to be stored.
Throws:
StandardException - Standard exception policy.
See Also:
ScanController.fetch(org.apache.derby.iapi.types.DataValueDescriptor[])

getScanInfo

public ScanInfo getScanInfo()
                     throws StandardException
Return ScanInfo object which describes performance of scan.

Return ScanInfo object which contains information about the current scan.

Specified by:
getScanInfo in interface GenericScanController
Returns:
The ScanInfo object which contains info about current scan.
Throws:
StandardException - Standard exception policy.
See Also:
ScanInfo

isCurrentPositionDeleted

public boolean isCurrentPositionDeleted()
                                 throws StandardException
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.

Specified by:
isCurrentPositionDeleted in interface ScanController
Throws:
StandardException - Standard exception policy.

isKeyed

public boolean isKeyed()
Return whether this is a keyed conglomerate.

Specified by:
isKeyed in interface GenericScanController
Returns:
whether this is a keyed conglomerate.

next

public boolean next()
             throws StandardException
Move to the next position in the scan.

Specified by:
next in interface ScanController
Returns:
True if there is a next position in the scan, false if there isn't.
Throws:
StandardException - Standard exception policy.
See Also:
ScanController.next()

fetchNext

public boolean fetchNext(DataValueDescriptor[] row)
                  throws StandardException
Fetch the row at the next position of the Scan. If there is a valid next position in the scan then the value in the template storable row is replaced with the value of the row at the current scan position. The columns of the template row must be of the same type as the actual columns in the underlying conglomerate. The resulting contents of templateRow after a fetchNext() which returns false is undefined. The result of calling fetchNext(row) is exactly logically equivalent to making a next() call followed by a fetch(row) call. This interface allows implementations to optimize the 2 calls if possible.

Specified by:
fetchNext in interface ScanController
Parameters:
row - The template row into which the value of the next position in the scan is to be stored.
Returns:
True if there is a next position in the scan, false if there isn't.
Throws:
StandardException - Standard exception policy.
See Also:
ScanController.fetch(org.apache.derby.iapi.types.DataValueDescriptor[]), RowUtil

fetchNextGroup

public int fetchNextGroup(DataValueDescriptor[][] row_array,
                          RowLocation[] rowloc_array)
                   throws StandardException
Fetch the next N rows from the table.

The client allocates an array of N rows and passes it into the fetchNextSet() call. This routine does the equivalent of N fetchNext() calls, filling in each of the rows in the array. Locking is performed exactly as if the N fetchNext() calls had been made.

It is up to Access how many rows to return. fetchNextSet() will return how many rows were filled in. If fetchNextSet() returns 0 then the scan is complete, (ie. the scan is in the same state as if fetchNext() had returned false). If the scan is not complete then fetchNext() will return (1 <= row_count <= N).

The current position of the scan is undefined if fetchNextSet() is used (ie. mixing fetch()/fetchNext() and fetchNextSet() calls in a single scan does not work). This is because a fetchNextSet() request for 5 rows from a heap where the first 2 rows qualify, but no other rows qualify will result in the scan being positioned at the end of the table, while if 5 rows did qualify the scan will be positioned on the 5th row.

Qualifiers, start and stop positioning of the openscan are applied just as in a normal scan.

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.

Expected usage: // allocate an array of 5 empty row templates DataValueDescriptor[][] row_array = allocate_row_array(5); int row_cnt = 0; scan = openScan(); while ((row_cnt = scan.fetchNextSet(row_array) != 0) { // I got "row_cnt" rows from the scan. These rows will be // found in row_array[0] through row_array[row_cnt - 1] }

RESOLVE - This interface is being provided so that we can prototype the performance results it can achieve. If it looks like this interface is useful, it is very likely we will look into a better way to tie together the now 4 different fetch interfaces: fetch, fetchNext(), fetchNextGroup(), and fetchSet().

Specified by:
fetchNextGroup in interface GroupFetchScanController
Parameters:
row_array - The array of rows to copy rows into. row_array[].length must >= 1. This routine assumes that all entries in the array contain complete template rows.
rowloc_array - If non-null, the array of row locations to copy into. If null, no row locations are retrieved.
Returns:
The number of qualifying rows found and copied into the provided array of rows. If 0 then the scan is complete, otherwise the return value will be: 1 <= row_count <= row_array.length
Throws:
StandardException - Standard exception policy.

fetchNextGroup

public int fetchNextGroup(DataValueDescriptor[][] row_array,
                          RowLocation[] old_rowloc_array,
                          RowLocation[] new_rowloc_array)
                   throws StandardException
Specified by:
fetchNextGroup in interface GroupFetchScanController
Throws:
StandardException

fetchSet

public void fetchSet(long max_rowcnt,
                     int[] key_column_numbers,
                     BackingStoreHashtable hash_table)
              throws StandardException
Insert all rows that qualify for the current scan into the input Hash table.

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 BackingStoreHashtable 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.

Note, that for this routine to work efficiently the caller must ensure that the object in row[key_column_number] implements the hashCode and equals method as appropriate for it's datatype.

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); } }

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?

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.

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."

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.

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.

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.

Specified by:
fetchSet in interface ScanManager
Parameters:
max_rowcnt - The maximum number of rows to insert into the Hash table. Pass in -1 if there is no maximum.
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).
hash_table - The java HashTable to load into.
Returns:
boolean indicating that the fetch set succeeded. If it failed Hashtable.clear() will be called leaving an empty table.
Throws:
StandardException - Standard exception policy.

reopenScan

public final void reopenScan(DataValueDescriptor[] startKeyValue,
                             int startSearchOperator,
                             Qualifier[][] qualifier,
                             DataValueDescriptor[] stopKeyValue,
                             int stopSearchOperator)
                      throws StandardException
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.

Specified by:
reopenScan in interface GenericScanController
Parameters:
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.
startSearchOperator - an operator which defines how the startKeyValue is to be searched for. If startSearchOperation 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.
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.
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.
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.
Throws:
StandardException - Standard exception policy.

reopenScanByRowLocation

public void reopenScanByRowLocation(RowLocation startRowLocation,
                                    Qualifier[][] qualifier)
                             throws StandardException
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.

The statistics gathered by the scan are not reset to 0 by a reopenScan(), rather they continue to accumulate.

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.

Specified by:
reopenScanByRowLocation in interface GenericScanController
Parameters:
startRowLocation - An existing RowLocation 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.
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.
Throws:
StandardException - Standard exception policy.

fetchLocation

public void fetchLocation(RowLocation templateLocation)
                   throws StandardException
Fetch the location of the current position in the scan.

Specified by:
fetchLocation in interface ScanController
Throws:
StandardException - Standard exception policy.
See Also:
ScanController.fetchLocation(org.apache.derby.iapi.types.RowLocation)

newRowLocationTemplate

public RowLocation newRowLocationTemplate()
                                   throws StandardException
Return a row location object of the correct type to be used in calls to fetchLocation.

Specified by:
newRowLocationTemplate in interface GenericScanController
Returns:
a row location object to be used in calls to fetchLocation.
Throws:
StandardException - Standard exception policy.
See Also:
GenericScanController.newRowLocationTemplate()

replace

public boolean replace(DataValueDescriptor[] row,
                       FormatableBitSet validColumns)
                throws StandardException
Replace the entire row at the current position of the scan. Unimplemented interface by btree, will throw an exception.

Specified by:
replace in interface ScanController
Returns:
true if the replace was successful, false if the current position is no longer valid (ie. if it was deleted).
Throws:
StandardException - Standard exception policy.
See Also:
ScanController.replace(org.apache.derby.iapi.types.DataValueDescriptor[], org.apache.derby.iapi.services.io.FormatableBitSet)

closeForEndTransaction

public boolean closeForEndTransaction(boolean closeHeldScan)
                               throws StandardException
Close the scan, a commit or abort is about to happen.

Specified by:
closeForEndTransaction in interface ScanManager
Parameters:
closeHeldScan - If true, means to close scan even if it has been opened to be kept opened across commit. This is used to close these scans on abort.
Returns:
boolean indicating that the close has resulted in a real close of the scan. A held scan will return false if called by closeForEndTransaction(false), otherwise it will return true. A non-held scan will always return true.
Throws:
StandardException - Standard exception policy.

savePosition

private void savePosition()
                   throws StandardException
Do work necessary to maintain the current position in the scan.

Save the current position of the scan as a key. Do whatever is necessary to maintain the current position of the scan. For some conglomerates this may be a no-op.

Throws:
StandardException - Standard exception policy.

savePosition

public void savePosition(Conglomerate conglom,
                         Page page)
                  throws StandardException
Do work necessary to maintain the current position in the scan.

The latched page in the conglomerate "congomid" is changing, do whatever is necessary to maintain the current position of the scan. For some conglomerates this may be a no-op.

Specified by:
savePosition in interface ScanManager
Parameters:
conglom - Conglomerate object of the conglomerate being changed.
page - Page in the conglomerate being changed.
Throws:
StandardException - Standard exception policy.

getCurrentRecordHandleForDebugging

public RecordHandle getCurrentRecordHandleForDebugging()

toString

public java.lang.String toString()

Built on Tue 2006-10-10 19:23:47+0200, from revision exported

Apache Derby V10.1 Engine Documentation - Copyright © 1997,2005 The Apache Software Foundation or its licensors, as applicable.