KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > store > access > conglomerate > GenericConglomerateController


1 /*
2
3    Derby - Class org.apache.derby.impl.store.access.conglomerate.GenericConglomerateController
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.conglomerate;
23
24 import org.apache.derby.iapi.reference.SQLState;
25
26 import org.apache.derby.iapi.services.sanity.SanityManager;
27
28 import org.apache.derby.iapi.error.StandardException;
29
30 import org.apache.derby.iapi.store.access.conglomerate.Conglomerate;
31 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
32 import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;
33
34 import org.apache.derby.iapi.store.access.ConglomerateController;
35 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo;
36 import org.apache.derby.iapi.store.access.Qualifier;
37 import org.apache.derby.iapi.store.access.RowUtil;
38 import org.apache.derby.iapi.store.access.SpaceInfo;
39
40 import org.apache.derby.iapi.store.raw.ContainerHandle;
41 import org.apache.derby.iapi.store.raw.FetchDescriptor;
42 import org.apache.derby.iapi.store.raw.Page;
43 import org.apache.derby.iapi.store.raw.RecordHandle;
44 import org.apache.derby.iapi.store.raw.Transaction;
45
46 import org.apache.derby.iapi.types.DataValueDescriptor;
47
48 import org.apache.derby.iapi.types.RowLocation;
49
50 import org.apache.derby.iapi.services.io.FormatableBitSet;
51
52 import java.util.Properties JavaDoc;
53
54
55 /**
56 **/

57
58 public abstract class GenericConglomerateController
59     extends GenericController implements ConglomerateController
60 {
61
62     /**************************************************************************
63      * Fields of the class
64      **************************************************************************
65      */

66
67     /**************************************************************************
68      * Constructors for This class:
69      **************************************************************************
70      */

71
72     /**************************************************************************
73      * Private/Protected methods of This class:
74      **************************************************************************
75      */

76
77     /**************************************************************************
78      * Public Methods of This class:
79      **************************************************************************
80      */

81
82
83     /**************************************************************************
84      * Public Methods implementing ConglomerateController which just
85      * delegate to OpenConglomerate:
86      **************************************************************************
87      */

88
89     /**************************************************************************
90      * Public Methods implementing ConglomerateController:
91      **************************************************************************
92      */

93
94     /**
95      * @see ConglomerateController#close
96      **/

97     public void close()
98         throws StandardException
99     {
100         super.close();
101
102         // If we are closed due to catching an error in the middle of init,
103
// xact_manager may not be set yet.
104
if ((open_conglom != null) && (open_conglom.getXactMgr() != null))
105             open_conglom.getXactMgr().closeMe(this);
106     }
107
108     /**
109      * Close conglomerate controller as part of terminating a transaction.
110      * <p>
111      * Use this call to close the conglomerate controller resources as part of
112      * committing or aborting a transaction. The normal close() routine may
113      * do some cleanup that is either unnecessary, or not correct due to the
114      * unknown condition of the controller following a transaction ending error.
115      * Use this call when closing all controllers as part of an abort of a
116      * transaction.
117      * <p)
118      * This call is meant to only be used internally by the Storage system,
119      * clients of the storage system should use the simple close() interface.
120      * <p>
121      * RESOLVE (mikem) - move this call to ConglomerateManager so it is
122      * obvious that non-access clients should not call this.
123      *
124      * @param closeHeldScan If true, means to close controller even if
125      * it has been opened to be kept opened
126      * across commit. This is
127      * used to close these controllers on abort.
128      *
129      * @return boolean indicating that the close has resulted in a real close
130      * of the controller. A held scan will return false if
131      * called by closeForEndTransaction(false), otherwise it
132      * will return true. A non-held scan will always return
133      * true.
134      *
135      * @exception StandardException Standard exception policy.
136      **/

137     public boolean closeForEndTransaction(boolean closeHeldScan)
138         throws StandardException
139     {
140         super.close();
141
142         if ((!open_conglom.getHold()) || closeHeldScan)
143         {
144             // If we are closed due to catching an error in the middle of init,
145
// xact_manager may not be set yet.
146
if ((open_conglom != null) && (open_conglom.getXactMgr() != null))
147                 open_conglom.getXactMgr().closeMe(this);
148
149             return(true);
150
151         }
152         else
153         {
154             return(false);
155         }
156     }
157
158     /**
159      * @see ConglomerateController#delete
160      **/

161     public boolean delete(RowLocation loc)
162         throws StandardException
163     {
164         if (open_conglom.isClosed())
165         {
166             if (open_conglom.getHold())
167             {
168                 if (open_conglom.isClosed())
169                     open_conglom.reopen();
170             }
171             else
172             {
173                 throw(
174                     StandardException.newException(
175                         SQLState.HEAP_IS_CLOSED,
176                         open_conglom.getConglomerate().getId()));
177             }
178         }
179
180         RowPosition pos = new RowPosition();
181
182         getRowPositionFromRowLocation(loc, pos);
183
184         if (!open_conglom.latchPage(pos))
185         {
186             return false;
187         }
188
189         open_conglom.lockPositionForWrite(pos, false /* not an insert */, true);
190
191         boolean ret_val = true;
192
193         // RESOLVE (mikem) - RECID - performance could be better if we did not
194
// have to call isDeletedAtSlot().
195

196         if (pos.current_page.isDeletedAtSlot(pos.current_slot))
197         {
198             ret_val = false;
199         }
200         else
201         {
202             // Delete the row
203
pos.current_page.deleteAtSlot(
204                 pos.current_slot, true, (LogicalUndo) null);
205
206             // try to reclaim rows when the page is only full of deleted rows,
207
// or in the special case of the first page when all rows except the
208
// "control row" are deleted. Or if the row we just deleted is
209
// a long row or has a long column.
210
if (pos.current_page.shouldReclaimSpace(
211                 pos.current_page.getPageNumber() == 1 ? 1 : 0,
212                 pos.current_slot))
213             {
214                 queueDeletePostCommitWork(pos);
215             }
216         }
217
218         pos.current_page.unlatch();
219
220         return(ret_val);
221     }
222
223     /**
224      * @see ConglomerateController#fetch
225      **/

226     public boolean fetch(
227     RowLocation loc,
228     DataValueDescriptor[] row,
229     FormatableBitSet validColumns)
230         throws StandardException
231     {
232         if (open_conglom.isClosed())
233         {
234             if (open_conglom.getHold())
235             {
236                 if (open_conglom.isClosed())
237                     open_conglom.reopen();
238             }
239             else
240             {
241                 throw(
242                     StandardException.newException(
243                         SQLState.HEAP_IS_CLOSED,
244                         open_conglom.getConglomerate().getId()));
245             }
246         }
247
248         if (SanityManager.DEBUG)
249         {
250             // Make sure valid columns are in the list. The RowUtil
251
// call is too expensive to make in a released system for
252
// every fetch.
253
int invalidColumn =
254                 RowUtil.columnOutOfRange(
255                     row, validColumns, open_conglom.getFormatIds().length);
256
257             if (invalidColumn >= 0)
258             {
259                 throw(StandardException.newException(
260                         SQLState.HEAP_TEMPLATE_MISMATCH,
261                         new Long JavaDoc(invalidColumn),
262                         new Long JavaDoc(open_conglom.getFormatIds().length)));
263             }
264         }
265
266         // Get the record handle out of its wrapper.
267

268         RowPosition pos = new RowPosition();
269
270         getRowPositionFromRowLocation(loc, pos);
271
272         if (!open_conglom.latchPage(pos))
273         {
274             return(false);
275         }
276
277
278         // Do not get U row lock - only get X or S. There is no good point
279
// currently to convert the U lock to an S lock, we don't know when
280
// the calling code is through with the lock.
281
// RESOLVE (mikem) - talk to language and see if it is worth it to
282
// get U lock and have language call back when we should take
283
// appropriate action on the U lock.
284

285         if (open_conglom.isForUpdate())
286         {
287             open_conglom.lockPositionForWrite(
288                 pos, false /* not an insert */, true);
289         }
290         else
291         {
292             open_conglom.lockPositionForRead(
293                 pos, (RowPosition) null, false, true);
294         }
295
296         // Fetch the row.
297
// RESOLVE (STO061) - don't know whether the fetch is for update or not.
298
//
299
// RESOLVE (mikem) - get rid of new here.
300
boolean ret_val =
301             (pos.current_page.fetchFromSlot(
302                 pos.current_rh, pos.current_slot,
303                 row,
304                 new FetchDescriptor(
305                     row.length, validColumns, (Qualifier[][]) null),
306                 false) != null);
307
308         // RESOLVE (mikem) - should be some way to hide this in the unlock call,
309
// and just always make the unlock call.
310

311         if (!open_conglom.isForUpdate())
312             open_conglom.unlockPositionAfterRead(pos);
313
314         pos.current_page.unlatch();
315
316         return(ret_val);
317     }
318
319     /**
320      * @see ConglomerateController#fetch
321      **/

322     public boolean fetch(
323     RowLocation loc,
324     DataValueDescriptor[] row,
325     FormatableBitSet validColumns,
326     boolean waitForLock)
327         throws StandardException
328     {
329         if (open_conglom.isClosed())
330         {
331             if (open_conglom.getHold())
332             {
333                 if (open_conglom.isClosed())
334                     open_conglom.reopen();
335             }
336             else
337             {
338                 throw(
339                     StandardException.newException(
340                         SQLState.HEAP_IS_CLOSED,
341                         open_conglom.getConglomerate().getId()));
342             }
343         }
344
345         if (SanityManager.DEBUG)
346         {
347             // Make sure valid columns are in the list. The RowUtil
348
// call is too expensive to make in a released system for
349
// every fetch.
350
int invalidColumn =
351                 RowUtil.columnOutOfRange(
352                     row, validColumns, open_conglom.getFormatIds().length);
353
354             if (invalidColumn >= 0)
355             {
356                 throw(StandardException.newException(
357                         SQLState.HEAP_TEMPLATE_MISMATCH,
358                         new Long JavaDoc(invalidColumn),
359                         new Long JavaDoc(open_conglom.getFormatIds().length)));
360             }
361         }
362
363         // Get the record handle out of its wrapper.
364

365         RowPosition pos = new RowPosition();
366
367         getRowPositionFromRowLocation(loc, pos);
368
369         if (!open_conglom.latchPage(pos))
370         {
371             return false;
372         }
373
374         // Do not get U row lock - only get X or S. There is not good point
375
// currently to convert the U lock to an S lock, we don't know when
376
// the calling code is through with the lock.
377
// RESOLVE (mikem) - talk to language and see if it is worth it to
378
// get U lock and have language call back when we should take
379
// appropriate action on the U lock.
380

381         if (open_conglom.isForUpdate())
382         {
383             open_conglom.lockPositionForWrite(
384                 pos, false /* not an insert */, waitForLock);
385         }
386         else
387         {
388             open_conglom.lockPositionForRead(
389                 pos, (RowPosition) null, false, waitForLock);
390         }
391
392         // Fetch the row.
393
// RESOLVE (STO061) - don't know whether the fetch is for update or not.
394
//
395
//
396
// RESOLVE (mikem) - get rid of new here.
397
boolean ret_val =
398             (pos.current_page.fetchFromSlot(
399                 pos.current_rh, pos.current_slot,
400                 row,
401                 new FetchDescriptor(
402                     row.length, validColumns, (Qualifier[][]) null),
403                 false) != null);
404
405         // RESOLVE (mikem) - should be some way to hide this in the unlock call,
406
// and just always make the unlock call.
407
if (!open_conglom.isForUpdate())
408             open_conglom.unlockPositionAfterRead(pos);
409
410         pos.current_page.unlatch();
411
412         return(ret_val);
413     }
414
415
416     /**
417      * @see ConglomerateController#replace
418      **/

419     public boolean replace(
420     RowLocation loc,
421     DataValueDescriptor[] row,
422     FormatableBitSet validColumns)
423         throws StandardException
424     {
425         if (open_conglom.isClosed())
426         {
427             if (open_conglom.getHold())
428             {
429                 if (open_conglom.isClosed())
430                     open_conglom.reopen();
431             }
432             else
433             {
434                 throw(
435                     StandardException.newException(
436                         SQLState.HEAP_IS_CLOSED,
437                         open_conglom.getConglomerate().getId()));
438             }
439         }
440
441         if (SanityManager.DEBUG)
442         {
443             // Make sure valid columns are in the list. The RowUtil
444
// call is too expensive to make in a released system for
445
// every fetch.
446
int invalidColumn =
447                 RowUtil.columnOutOfRange(
448                     row, validColumns, open_conglom.getFormatIds().length);
449
450             if (invalidColumn >= 0)
451             {
452                 throw(StandardException.newException(
453                         SQLState.HEAP_TEMPLATE_MISMATCH,
454                         new Long JavaDoc(invalidColumn),
455                         new Long JavaDoc(open_conglom.getFormatIds().length)));
456             }
457         }
458
459         RowPosition pos = new RowPosition();
460
461         getRowPositionFromRowLocation(loc, pos);
462
463         if (!open_conglom.latchPage(pos))
464         {
465             return false;
466         }
467
468         open_conglom.lockPositionForWrite(pos, false, true);
469
470         boolean ret_val = true;
471
472         if (pos.current_page.isDeletedAtSlot(pos.current_slot))
473         {
474             ret_val = false;
475         }
476         else
477         {
478             // Update the record.
479
pos.current_page.updateAtSlot(pos.current_slot, row, validColumns);
480         }
481
482         pos.current_page.unlatch();
483
484         return(ret_val);
485     }
486 }
487
Popular Tags