KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > store > access > heap > HeapScan


1 /*
2
3    Derby - Class org.apache.derby.impl.store.access.heap.HeapScan
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.store.access.heap;
23
24
25 /**
26
27   A heap scan object represents an instance of an scan on a heap conglomerate.
28
29 **/

30
31 import org.apache.derby.iapi.reference.SQLState;
32
33 import org.apache.derby.iapi.services.sanity.SanityManager;
34
35 import org.apache.derby.iapi.services.io.Storable;
36
37 import org.apache.derby.iapi.error.StandardException;
38
39 import org.apache.derby.iapi.store.access.conglomerate.Conglomerate;
40 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
41 import org.apache.derby.iapi.store.access.conglomerate.ScanManager;
42 import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;
43
44 import org.apache.derby.iapi.store.access.ConglomerateController;
45 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo;
46 import org.apache.derby.iapi.store.access.Qualifier;
47 import org.apache.derby.iapi.store.access.RowUtil;
48 import org.apache.derby.iapi.store.access.ScanInfo;
49 import org.apache.derby.iapi.store.access.ScanController;
50
51 import org.apache.derby.iapi.types.RowLocation;
52
53 import org.apache.derby.iapi.store.raw.ContainerHandle;
54 import org.apache.derby.iapi.store.raw.LockingPolicy;
55 import org.apache.derby.iapi.store.raw.Transaction;
56 import org.apache.derby.iapi.store.raw.Page;
57 import org.apache.derby.iapi.store.raw.RecordHandle;
58
59 import org.apache.derby.iapi.types.DataValueDescriptor;
60
61 import org.apache.derby.impl.store.access.conglomerate.ConglomerateUtil;
62 import org.apache.derby.impl.store.access.conglomerate.GenericScanController;
63 import org.apache.derby.impl.store.access.conglomerate.RowPosition;
64
65 import org.apache.derby.iapi.store.access.BackingStoreHashtable;
66 import org.apache.derby.iapi.services.io.FormatableBitSet;
67
68 import java.util.Hashtable JavaDoc;
69 import java.util.Vector JavaDoc;
70
71 class HeapScan
72     extends GenericScanController implements ScanManager
73 {
74
75     /**************************************************************************
76      * Constants of HeapScan
77      **************************************************************************
78      */

79
80     /**************************************************************************
81      * Fields of HeapScan
82      **************************************************************************
83      */

84
85     /**
86      * A 1 element array to turn fetchNext and fetch calls into
87      * fetchNextGroup calls.
88      **/

89     private DataValueDescriptor[][] fetchNext_one_slot_array =
90         new DataValueDescriptor[1][];
91
92
93     /**************************************************************************
94      * Constructors for This class:
95      **************************************************************************
96      */

97
98     /**
99      ** The only constructor for a heap scan returns a scan in the
100      ** closed state, the caller must call open.
101      **/

102     
103     public HeapScan()
104     {
105     }
106
107     /**************************************************************************
108      * Protected concrete impl of abstract methods of
109      * GenericController class:
110      **************************************************************************
111      */

112     protected void queueDeletePostCommitWork(
113     RowPosition pos)
114         throws StandardException
115     {
116         TransactionManager xact_mgr = open_conglom.getXactMgr();
117
118         xact_mgr.addPostCommitWork(
119             new HeapPostCommit(
120                 xact_mgr.getAccessManager(),
121                 (Heap) open_conglom.getConglomerate(),
122                 pos.current_page.getPageNumber()));
123     }
124
125     /**************************************************************************
126      * Private/Protected methods of This class:
127      **************************************************************************
128      */

129     protected void setRowLocationArray(
130     RowLocation[] rowloc_array,
131     int index,
132     RowPosition pos)
133         throws StandardException
134     {
135         if (rowloc_array[index] == null)
136         {
137             rowloc_array[index] = new HeapRowLocation(pos.current_rh);
138         }
139         else
140         {
141             if (SanityManager.DEBUG)
142             {
143                 SanityManager.ASSERT(
144                     rowloc_array[index] instanceof HeapRowLocation);
145             }
146
147             ((HeapRowLocation)rowloc_array[index]).setFrom(pos.current_rh);
148         }
149     }
150
151     protected void setRowLocationArray(
152     RowLocation[] rowloc_array,
153     int index,
154     RecordHandle rh)
155         throws StandardException
156     {
157         if (rowloc_array[index] == null)
158         {
159             rowloc_array[index] = new HeapRowLocation(rh);
160         }
161         else
162         {
163             if (SanityManager.DEBUG)
164             {
165                 SanityManager.ASSERT(
166                     rowloc_array[index] instanceof HeapRowLocation);
167             }
168
169             ((HeapRowLocation)rowloc_array[index]).setFrom(rh);
170         }
171     }
172
173     /**
174      * Reposition the current scan and sets the necessary locks.
175      *
176      * @param rh An existing RecordHandle within the conglomerate,
177      * at which to position the start of the scan. The scan will begin at this
178      * location and continue forward until the end of the conglomerate.
179      * Positioning at a non-existent RowLocation (ie. an invalid one or one that
180      * had been deleted), will result in an exception being thrown when the
181      * first next operation is attempted.
182      * @return true if the scan was successfully repositioned
183      *
184      * @exception StandardException Standard exception policy.
185      */

186     private boolean reopenScanByRecordHandleAndSetLocks (RecordHandle rh)
187             throws StandardException
188     {
189         if (rh == null)
190         {
191             return (false);
192         }
193         
194         // Unlock current position
195
if (scan_position.current_rh != null)
196         {
197             open_conglom.unlockPositionAfterRead(scan_position);
198         }
199         
200         // Position scan at new row
201
scan_position.current_rh = rh;
202         scan_position.current_rh_qualified = false;
203         
204         // Latch page and reposition scan
205
final boolean rowLocationDisappeared =
206             open_conglom.latchPageAndRepositionScan(scan_position);
207         
208         if (!rowLocationDisappeared)
209         {
210             setScanState(SCAN_INPROGRESS);
211             open_conglom.lockPositionForRead
212                 (scan_position, null, true, true);
213         }
214         
215         // Unlatch page
216
scan_position.unlatch();
217         
218         return (!rowLocationDisappeared);
219     }
220
221     /**
222     Fetch the row at the next position of the Scan.
223
224     If there is a valid next position in the scan then
225     the value in the template storable row is replaced
226     with the value of the row at the current scan
227     position. The columns of the template row must
228     be of the same type as the actual columns in the
229     underlying conglomerate.
230
231     The resulting contents of templateRow after a fetchNext()
232     which returns false is undefined.
233
234     The result of calling fetchNext(row) is exactly logically
235     equivalent to making a next() call followed by a fetch(row)
236     call. This interface allows implementations to optimize
237     the 2 calls if possible.
238
239     @param fetch_row The template row into which the value
240     of the next position in the scan is to be stored.
241
242     @return True if there is a next position in the scan,
243     false if there isn't.
244
245     @exception StandardException Standard exception policy.
246     **/

247     public boolean fetchNext(DataValueDescriptor[] fetch_row)
248         throws StandardException
249     {
250         // Turn this call into a group fetch of a 1 element group.
251
if (fetch_row == null)
252             fetchNext_one_slot_array[0] = RowUtil.EMPTY_ROW;
253         else
254             fetchNext_one_slot_array[0] = fetch_row;
255
256         boolean ret_val =
257             fetchRows(
258                 fetchNext_one_slot_array,
259                 (RowLocation[]) null,
260                 (BackingStoreHashtable) null,
261                 1,
262                 (int[]) null) == 1;
263
264         return(ret_val);
265     }
266
267
268     /**
269     @see ScanController#next
270     **/

271     public boolean next()
272         throws StandardException
273     {
274         // if there is no row template from the caller, we need to
275
// read the row into something, Use the scratch row.
276
// We could optimize this, if there are no qualifiers and read
277
// into a zero column row, but callers should be using fetchNext()
278
// instead.
279
fetchNext_one_slot_array[0] = open_conglom.getRuntimeMem().get_scratch_row();
280
281         boolean ret_val =
282             fetchRows(
283                 fetchNext_one_slot_array,
284                 (RowLocation[]) null,
285                 (BackingStoreHashtable) null,
286                 1,
287                 (int[]) null) == 1;
288
289         return(ret_val);
290     }
291
292     /**
293      * @see ScanController#positionAtRowLocation
294      */

295     public boolean positionAtRowLocation(RowLocation rl) throws StandardException {
296         if (open_conglom.isClosed() && !rowLocationsInvalidated)
297         {
298             reopenAfterEndTransaction();
299         }
300         
301         if (rowLocationsInvalidated)
302         {
303             return(false);
304             
305         } else {
306             return(reopenScanByRecordHandleAndSetLocks
307                 (((HeapRowLocation)rl).
308                  getRecordHandle(open_conglom.getContainer())));
309         }
310     }
311
312     /**************************************************************************
313      * Public Methods of ScanController interface:
314      **************************************************************************
315      */

316
317     /**
318     @see ScanController#fetchLocation
319     **/

320     public void fetchLocation(RowLocation templateLocation)
321         throws StandardException
322     {
323         if (open_conglom.getContainer() == null ||
324             scan_position.current_rh == null)
325         {
326             throw StandardException.newException(
327                     SQLState.HEAP_SCAN_NOT_POSITIONED);
328         }
329         HeapRowLocation hrl = (HeapRowLocation) templateLocation;
330         hrl.setFrom(scan_position.current_rh);
331     }
332
333     public int fetchNextGroup(
334     DataValueDescriptor[][] row_array,
335     RowLocation[] rowloc_array)
336         throws StandardException
337     {
338         return(
339             fetchRows(
340                 row_array,
341                 rowloc_array,
342                 (BackingStoreHashtable) null,
343                 row_array.length,
344                 (int[]) null));
345     }
346
347     public int fetchNextGroup(
348     DataValueDescriptor[][] row_array,
349     RowLocation[] old_rowloc_array,
350     RowLocation[] new_rowloc_array)
351         throws StandardException
352     {
353         throw(StandardException.newException(
354                 SQLState.HEAP_UNIMPLEMENTED_FEATURE));
355     }
356
357
358     /**
359      * Return ScanInfo object which describes performance of scan.
360      * <p>
361      * Return ScanInfo object which contains information about the current
362      * scan.
363      * <p>
364      *
365      * @see ScanInfo
366      *
367      * @return The ScanInfo object which contains info about current scan.
368      *
369      * @exception StandardException Standard exception policy.
370      **/

371     public ScanInfo getScanInfo()
372         throws StandardException
373     {
374         return(new HeapScanInfo(this));
375     }
376
377     /**
378     Reposition the current scan. This call is semantically the same as if
379     the current scan had been closed and a openScan() had been called instead.
380     The scan is reopened against the same conglomerate, and the scan
381     is reopened with the same "scan column list", "hold" and "forUpdate"
382     parameters passed in the original openScan.
383     <p>
384     The statistics gathered by the scan are not reset to 0 by a reopenScan(),
385     rather they continue to accumulate.
386     <p>
387     Note that this operation is currently only supported on Heap conglomerates.
388     Also note that order of rows within are heap are not guaranteed, so for
389     instance positioning at a RowLocation in the "middle" of a heap, then
390     inserting more data, then continuing the scan is not guaranteed to see
391     the new rows - they may be put in the "beginning" of the heap.
392
393     @param startRowLocation An existing RowLocation within the conglomerate,
394     at which to position the start of the scan. The scan will begin at this
395     location and continue forward until the end of the conglomerate.
396     Positioning at a non-existent RowLocation (ie. an invalid one or one that
397     had been deleted), will result in an exception being thrown when the
398     first next operation is attempted.
399
400     @param qualifier An array of qualifiers which, applied
401     to each key, restrict the rows returned by the scan. Rows
402     for which any one of the qualifiers returns false are not
403     returned by the scan. If null, all rows are returned.
404
405     @exception StandardException Standard exception policy.
406     **/

407     public void reopenScanByRowLocation(
408     RowLocation startRowLocation,
409     Qualifier qualifier[][])
410         throws StandardException
411     {
412         reopenScanByRecordHandle(
413             ((HeapRowLocation) startRowLocation).getRecordHandle(
414                  open_conglom.getContainer()),
415             qualifier);
416     }
417
418
419     /*
420     ** Methods of ScanManager
421     */

422
423     /**
424      * Do work necessary to maintain the current position in the scan.
425      * <p>
426      * The latched page in the conglomerate "congomid" is changing, do
427      * whatever is necessary to maintain the current position of the scan.
428      * For some conglomerates this may be a no-op.
429      * <p>
430      *
431      * @param conglom Conglomerate being changed.
432      * @param page Page in the conglomerate being changed.
433      *
434      * @exception StandardException Standard exception policy.
435      **/

436     public void savePosition(Conglomerate conglom, Page page)
437         throws StandardException
438     {
439         // RESOLVE (mikem), under the current implementation all scans within
440
// a transaction are called rather than just the ones with the right
441
// conglom. For now just have heaps ignore the call.
442

443         // throw HeapOperationException.unimplementedFeature();
444
return;
445     }
446 }
447
Popular Tags