001: /*
002:
003: Derby - Class org.apache.derby.iapi.store.access.GroupFetchScanController
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.iapi.store.access;
023:
024: import org.apache.derby.iapi.services.io.Storable;
025:
026: import org.apache.derby.iapi.error.StandardException;
027:
028: import org.apache.derby.iapi.types.DataValueDescriptor;
029:
030: import org.apache.derby.iapi.types.RowLocation;
031:
032: import org.apache.derby.iapi.services.io.FormatableBitSet;
033:
034: import java.util.Hashtable;
035:
036: /**
037: This scan controller can only be used for group fetch, no update
038: operations are supported, use ScanController if you need scan interfaces
039: other than group fetch.
040: <p>
041: In general group fetch will be more efficient than using the
042: ScanController fetchNext() interface to get rows one at a time. The
043: performance comes from reducing the per call overhead of getting
044: a row. Also this interface can, depending on the requested isolation
045: level, possibly do more efficient locking.
046: <p>
047: Group fetch scans are opened from a TransactionController.
048:
049: @see TransactionController#openScan
050: @see RowCountable
051: @see GenericScanController
052:
053: **/
054:
055: public interface GroupFetchScanController extends GenericScanController {
056: /**
057: * Fetch the next N rows from the table.
058: * <p>
059: * The client allocates an array of N rows and passes it into the
060: * fetchNextSet() call. The client must at least allocate a row and
061: * set row_array[0] to this row. The client can optionally either leave
062: * the rest of array entries null, or allocate rows to the slots.
063: * If access finds an entry to be null, and wants to read a row into
064: * it, it will allocate a row to the slot. Once fetchNextGroup() returns
065: * "ownership" of the row passes back to the client, access will not
066: * keep references to the allocated row. Expected usage is that
067: * the client will specify an array of some number (say 10), and then
068: * only allocate a single row. This way if only 1 row qualifies only
069: * one row will have been allocated.
070: * <p>
071: * This routine does the equivalent of N
072: * fetchNext() calls, filling in each of the rows in the array.
073: * Locking is performed exactly as if the N fetchNext() calls had
074: * been made.
075: * <p>
076: * It is up to Access how many rows to return. fetchNextGroup() will
077: * return how many rows were filled in. If fetchNextGroup() returns 0
078: * then the scan is complete, (ie. the scan is in the same state as if
079: * fetchNext() had returned false). If the scan is not complete then
080: * fetchNext() will return (1 <= row_count <= N).
081: * <p>
082: * The current position of the scan is undefined if fetchNextSet()
083: * is used (ie. mixing fetch()/fetchNext() and fetchNextSet() calls
084: * in a single scan does not work). This is because a fetchNextSet()
085: * request for 5 rows from a heap where the first 2 rows qualify, but
086: * no other rows qualify will result in the scan being positioned at
087: * the end of the table, while if 5 rows did qualify the scan will be
088: * positioned on the 5th row.
089: * <p>
090: * If the row loc array is non-null then for each row fetched into
091: * the row array, a corresponding fetchLocation() call will be made to
092: * fill in the rowloc_array. This array, like the row array can be
093: * initialized with only one non-null RowLocation and access will
094: * allocate the rest on demand.
095: * <p>
096: * Qualifiers, start and stop positioning of the openscan are applied
097: * just as in a normal scan.
098: * <p>
099: * The columns of the row will be the standard columns returned as
100: * part of a scan, as described by the validColumns - see openScan for
101: * description.
102: * <p>
103: * Expected usage:
104: *
105: * // allocate an array of 5 empty rows
106: * DataValueDescriptor[][] row_array = allocate_row_array(5);
107: * int row_cnt = 0;
108: *
109: * scan = openScan();
110: *
111: * while ((row_cnt = scan.fetchNextSet(row_array, null) != 0)
112: * {
113: * // I got "row_cnt" rows from the scan. These rows will be
114: * // found in row_array[0] through row_array[row_cnt - 1]
115: * }
116: *
117: * <p>
118: * @return The number of qualifying rows found and copied into the
119: * provided array of rows. If 0 then the scan is complete,
120: * otherwise the return value will be:
121: * 1 <= row_count <= row_array.length
122: *
123: * @param row_array The array of rows to copy rows into.
124: * row_array[].length must >= 1. The first entry
125: * must be non-null destination rows, other entries
126: * may be null and will be allocated by access
127: * if needed.
128: *
129: * @param rowloc_array If non-null, the array of row locations to
130: * copy into. If null, no row locations are
131: * retrieved.
132: *
133: * @exception StandardException Standard exception policy.
134: **/
135: public int fetchNextGroup(DataValueDescriptor[][] row_array,
136: RowLocation[] rowloc_array) throws StandardException;
137:
138: public int fetchNextGroup(DataValueDescriptor[][] row_array,
139: RowLocation[] oldrowloc_array, RowLocation[] newrowloc_array)
140: throws StandardException;
141:
142: /**
143: Move to the next position in the scan. If this is the first
144: call to next(), the position is set to the first row.
145: Returns false if there is not a next row to move to.
146: It is possible, but not guaranteed, that this method could return
147: true again, after returning false, if some other operation in the same
148: transaction appended a row to the underlying conglomerate.
149:
150: @return True if there is a next position in the scan,
151: false if there isn't.
152:
153: @exception StandardException Standard exception policy.
154: **/
155: boolean next() throws StandardException;
156: }
|