KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.store.access.heap.Heap
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
23 package org.apache.derby.impl.store.access.heap;
24
25 import java.io.ObjectOutput JavaDoc;
26 import java.io.ObjectInput JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.util.Properties JavaDoc;
29
30 import org.apache.derby.iapi.reference.SQLState;
31
32 import org.apache.derby.iapi.services.io.ArrayInputStream;
33 import org.apache.derby.iapi.services.io.FormatableBitSet;
34
35 import org.apache.derby.iapi.services.sanity.SanityManager;
36
37 import org.apache.derby.iapi.services.io.Formatable;
38 import org.apache.derby.iapi.services.io.FormatIdUtil;
39 import org.apache.derby.iapi.services.io.Storable;
40 import org.apache.derby.iapi.services.io.StoredFormatIds;
41
42 import org.apache.derby.iapi.error.StandardException;
43
44 import org.apache.derby.iapi.store.access.conglomerate.Conglomerate;
45 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
46 import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;
47 import org.apache.derby.iapi.store.access.conglomerate.ScanManager;
48 import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;
49
50 import org.apache.derby.iapi.store.access.AccessFactoryGlobals;
51 import org.apache.derby.iapi.store.access.ConglomerateController;
52 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo;
53 import org.apache.derby.iapi.store.access.Qualifier;
54 import org.apache.derby.iapi.store.access.RowLocationRetRowSource;
55 import org.apache.derby.iapi.store.access.RowUtil;
56 import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo;
57 import org.apache.derby.iapi.store.access.StoreCostController;
58 import org.apache.derby.iapi.store.access.TransactionController;
59
60 import org.apache.derby.iapi.store.raw.ContainerKey;
61 import org.apache.derby.iapi.store.raw.ContainerHandle;
62 import org.apache.derby.iapi.store.raw.LockingPolicy;
63 import org.apache.derby.iapi.store.raw.Transaction;
64 import org.apache.derby.iapi.store.raw.Page;
65 import org.apache.derby.iapi.store.raw.RawStoreFactory;
66 import org.apache.derby.iapi.store.raw.RecordHandle;
67
68 import org.apache.derby.iapi.types.DataValueDescriptor;
69
70 import org.apache.derby.iapi.services.cache.ClassSize;
71
72 import org.apache.derby.iapi.types.DataType;
73
74 import org.apache.derby.impl.store.access.conglomerate.ConglomerateUtil;
75 import org.apache.derby.impl.store.access.conglomerate.GenericConglomerate;
76 import org.apache.derby.impl.store.access.conglomerate.OpenConglomerate;
77 import org.apache.derby.impl.store.access.conglomerate.OpenConglomerateScratchSpace;
78
79 import java.sql.ResultSet JavaDoc;
80 import java.sql.SQLException JavaDoc;
81
82
83 /**
84  * @format_id ACCESS_HEAP_V1_ID
85  *
86  * @purpose The tag that describes the on disk representation of the Heap
87  * conglomerate object. The Heap conglomerate object is stored in
88  * a field of a row in the Conglomerate directory.
89  *
90  * @upgrade This format was made obsolete in the kimono release.
91  *
92  * @disk_layout
93  * containerid(long)
94  * segmentid(int)
95  **/

96
97 /**
98  * @format_id ACCESS_HEAP_V2_ID
99  *
100  * @purpose The tag that describes the on disk representation of the Heap
101  * conglomerate object. The Heap conglomerate object is stored in
102  * a field of a row in the Conglomerate directory.
103  *
104  * @upgrade The format id of this object is currently always read from disk
105  * as a separate column in the conglomerate directory. To read
106  * A conglomerate object from disk and upgrade it to the current
107  * version do the following:
108  *
109  * format_id = get format id from a separate column
110  * Upgradable conglom_obj = instantiate empty obj(format_id)
111  * read in conglom_obj from disk
112  * conglom = conglom_obj.upgradeToCurrent();
113  *
114  * @disk_layout
115  * format_of_this_conlgomerate(byte[])
116  * containerid(long)
117  * segmentid(int)
118  * number_of_columns(int)
119  * array_of_format_ids(byte[][])
120  **/

121
122 /**
123
124   A heap object corresponds to an instance of a heap conglomerate. It caches
125   information which makes it fast to open heap controllers from it.
126
127 **/

128
129 public final class Heap
130     extends GenericConglomerate
131     implements Conglomerate, StaticCompiledOpenConglomInfo
132 {
133
134     /*
135     ** Fields of Heap.
136     */

137
138     protected ContainerKey id;
139
140     /**
141      * The format id's of each of the columns in the heap table.
142      **/

143     int[] format_ids;
144
145     private static final int BASE_MEMORY_USAGE = ClassSize.estimateBaseFromCatalog( Heap.class);
146     private static final int CONTAINER_KEY_MEMORY_USAGE = ClassSize.estimateBaseFromCatalog( ContainerKey.class);
147
148     public int estimateMemoryUsage()
149     {
150         int sz = BASE_MEMORY_USAGE;
151
152         if( null != id)
153             sz += CONTAINER_KEY_MEMORY_USAGE;
154         if( null != format_ids)
155             sz += format_ids.length*ClassSize.getIntSize();
156         return sz;
157     } // end of estimateMemoryUsage
158

159     /*
160     ** Methods of Heap.
161     */

162
163     /* Constructors for This class: */
164
165     /**
166      * Zero arg constructor for Monitor to create empty object.
167      **/

168     public Heap()
169     {
170     }
171
172     /* Private/Protected methods of This class: */
173
174     /**
175      * Create a heap conglomerate.
176      * <p>
177      * Create a heap conglomerate. This method is called from the heap factory
178      * to create a new instance of a heap.
179      * <p>
180      *
181      * @exception StandardException Standard exception policy.
182      **/

183     protected void create(
184     Transaction rawtran,
185     int segmentId,
186     long input_containerid,
187     DataValueDescriptor[] template,
188     Properties JavaDoc properties,
189     int tmpFlag)
190         throws StandardException
191     {
192         // Create a container for the heap table with
193
// default minimumRecordSize to be at least
194
// MINIMUM_RECORD_SIZE_DEFAULT (12),
195
// to guarantee there is enough room for updates
196
// of the row.
197
// Here we only take care of the case that
198
// that the properties are set with the create
199
// statement. For the case when properties are
200
// not set with the create statement, it is taken
201
// care of in fileContainer.java: createInfoFromProp().
202
if (properties != null)
203         {
204             String JavaDoc value = properties.getProperty(
205                 RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER);
206
207             int minimumRecordSize =
208                 (value == null) ?
209                     RawStoreFactory.MINIMUM_RECORD_SIZE_DEFAULT :
210                     Integer.parseInt(value);
211
212             if (minimumRecordSize < RawStoreFactory.MINIMUM_RECORD_SIZE_DEFAULT)
213             {
214                 properties.put(
215                     RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER,
216                     Integer.toString(
217                         RawStoreFactory.MINIMUM_RECORD_SIZE_DEFAULT));
218             }
219         }
220
221         // Create a container for the heap with default page size.
222
long containerid =
223             rawtran.addContainer(
224                 segmentId, input_containerid,
225                 ContainerHandle.MODE_DEFAULT, properties, tmpFlag);
226
227         // Make sure the container was actually created.
228
if (containerid < 0)
229         {
230             throw StandardException.newException(
231                     SQLState.HEAP_CANT_CREATE_CONTAINER);
232         }
233
234         // Keep track of what segment the container's in.
235
id = new ContainerKey(segmentId, containerid);
236
237         // Heap requires a template representing every column in the table.
238
if ((template == null) || (template.length == 0))
239         {
240             throw StandardException.newException(
241                     SQLState.HEAP_COULD_NOT_CREATE_CONGLOMERATE);
242         }
243
244         // get format id's from each column in template and store it in the
245
// conglomerate state.
246
this.format_ids = ConglomerateUtil.createFormatIds(template);
247
248
249         // need to open the container and insert the row. Since we are
250
// creating it no need to bother with locking since no one can get
251
// to it until after we have created it and returned it's id.
252
ContainerHandle container = null;
253         Page page = null;
254
255         try
256         {
257             container =
258                 rawtran.openContainer(
259                     id, (LockingPolicy) null,
260                     ContainerHandle.MODE_FORUPDATE |
261                         (isTemporary() ? ContainerHandle.MODE_TEMP_IS_KEPT : 0));
262
263             // row in slot 0 of heap page 1 which is just a single column with
264
// the heap entry.
265
DataValueDescriptor[] control_row = new DataValueDescriptor[1];
266             control_row[0] = this;
267
268             page =
269                 container.getPage(ContainerHandle.FIRST_PAGE_NUMBER);
270
271             page.insertAtSlot(
272                 Page.FIRST_SLOT_NUMBER,
273                 control_row,
274                 (FormatableBitSet) null,
275                 (LogicalUndo) null,
276                 Page.INSERT_OVERFLOW,
277                 AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD);
278             page.unlatch();
279             page = null;
280
281             // Don't include the control row in the estimated row count.
282
container.setEstimatedRowCount(0, /* unused flag */ 0);
283         }
284         finally
285         {
286             if (container != null)
287                 container.close();
288             if (page !=null)
289                 page.unlatch();
290         }
291     }
292
293     /**
294      * Create a heap conglomerate during the boot process.
295      * <p>
296      * Manufacture a Heap Conglomerate out of "thin" air, to boot strap
297      * the system. Create an in-memory Heap Conglomerate with the input
298      * parameters, The caller will use this to open the conglomerate
299      * conglomerate and read the "real" values from disk. Conglom-conglom
300      * is always on segment 0.
301      *
302      *
303      * @param containerid The container id of the conglomerate.
304      * @param template Object array describing the columns of the heap.
305      **/

306     public void boot_create(
307     long containerid,
308     DataValueDescriptor[] template)
309     {
310         id = new ContainerKey(0, containerid);
311         this.format_ids = ConglomerateUtil.createFormatIds(template);
312     }
313
314     /*
315     ** Methods of Conglomerate
316     */

317
318     /**
319      * Add a column to the heap conglomerate.
320      * <p>
321      * This routine update's the in-memory object version of the Heap
322      * Conglomerate to have one more column of the type described by the
323      * input template column.
324      *
325      * @param column_id The column number to add this column at.
326      * @param template_column An instance of the column to be added to table.
327      *
328      * @exception StandardException Standard exception policy.
329      **/

330     public void addColumn(
331     TransactionManager xact_manager,
332     int column_id,
333     Storable template_column)
334         throws StandardException
335     {
336         // need to open the container and update the row containing the
337
// serialized format of the heap.
338
ContainerHandle container = null;
339         Page page = null;
340         Transaction rawtran = xact_manager.getRawStoreXact();
341
342         try
343         {
344             container =
345                 rawtran.openContainer(
346                     id,
347                     rawtran.newLockingPolicy(
348                         LockingPolicy.MODE_CONTAINER,
349                         TransactionController.ISOLATION_SERIALIZABLE, true),
350                     ContainerHandle.MODE_FORUPDATE |
351                         (isTemporary() ? ContainerHandle.MODE_TEMP_IS_KEPT : 0));
352
353             if (column_id != format_ids.length)
354             {
355                 if (SanityManager.DEBUG)
356                     SanityManager.THROWASSERT(
357                         "column_id = " + column_id +
358                         "format_ids.length = " + format_ids.length +
359                         "format_ids = " + format_ids);
360
361                 throw(StandardException.newException(
362                         SQLState.HEAP_TEMPLATE_MISMATCH,
363                         new Long JavaDoc(column_id),
364                         new Long JavaDoc(this.format_ids.length)));
365             }
366
367             // create a new array, and copy old values to it.
368
int[] old_format_ids = format_ids;
369             format_ids = new int[old_format_ids.length + 1];
370             System.arraycopy(
371                 old_format_ids, 0, format_ids, 0, old_format_ids.length);
372
373             // add the new column
374
format_ids[old_format_ids.length] =
375                 template_column.getTypeFormatId();
376
377            
378             // row in slot 0 of heap page 1 which is just a single column with
379
// the heap entry.
380
DataValueDescriptor[] control_row = new DataValueDescriptor[1];
381             control_row[0] = this;
382
383             page =
384                 container.getPage(ContainerHandle.FIRST_PAGE_NUMBER);
385
386             page.updateAtSlot(
387                 Page.FIRST_SLOT_NUMBER,
388                 control_row,
389                 (FormatableBitSet) null);
390
391             page.unlatch();
392             page = null;
393         }
394         finally
395         {
396             if (container != null)
397                 container.close();
398             if (page !=null)
399                 page.unlatch();
400         }
401
402         return;
403     }
404
405
406     /**
407     Drop this heap.
408     @see Conglomerate#drop
409
410     @exception StandardException Standard exception policy.
411     **/

412     public void drop(TransactionManager xact_manager)
413         throws StandardException
414     {
415         xact_manager.getRawStoreXact().dropContainer(id);
416     }
417
418     /**
419      * Retrieve the maximum value row in an ordered conglomerate.
420      * <p>
421      * Returns true and fetches the rightmost row of an ordered conglomerate
422      * into "fetchRow" if there is at least one row in the conglomerate. If
423      * there are no rows in the conglomerate it returns false.
424      * <p>
425      * Non-ordered conglomerates will not implement this interface, calls
426      * will generate a StandardException.
427      * <p>
428      * RESOLVE - this interface is temporary, long term equivalent (and more)
429      * functionality will be provided by the openBackwardScan() interface.
430      *
431      * @param conglomId The identifier of the conglomerate
432      * to open the scan for.
433      *
434      * @param open_mode Specifiy flags to control opening of table.
435      * OPENMODE_FORUPDATE - if set open the table for
436      * update otherwise open table shared.
437      * @param lock_level One of (MODE_TABLE, MODE_RECORD, or MODE_NONE).
438      *
439      * @param isolation_level The isolation level to lock the conglomerate at.
440      * One of (ISOLATION_READ_COMMITTED or
441      * ISOLATION_SERIALIZABLE).
442      *
443      * @param scanColumnList A description of which columns to return from
444      * every fetch in the scan. template,
445      * and scanColumnList work together
446      * to describe the row to be returned by the scan -
447      * see RowUtil for description of how these three
448      * parameters work together to describe a "row".
449      *
450      * @param fetchRow The row to retrieve the maximum value into.
451      *
452      * @return boolean indicating if a row was found and retrieved or not.
453      *
454      * @exception StandardException Standard exception policy.
455      **/

456     public boolean fetchMaxOnBTree(
457     TransactionManager xact_manager,
458     Transaction rawtran,
459     long conglomId,
460     int open_mode,
461     int lock_level,
462     LockingPolicy locking_policy,
463     int isolation_level,
464     FormatableBitSet scanColumnList,
465     DataValueDescriptor[] fetchRow)
466         throws StandardException
467     {
468         // no support for max on a heap table.
469
throw(StandardException.newException(
470                 SQLState.HEAP_UNIMPLEMENTED_FEATURE));
471     }
472
473     /**
474      * Get the id of the container of the conglomerate.
475      * <p>
476      * Will have to change when a conglomerate could have more than one
477      * container. The ContainerKey is a combination of the container id
478      * and segment id.
479      *
480      * @return The ContainerKey.
481      **/

482     public final ContainerKey getId()
483     {
484         return(id);
485     }
486
487
488     public final long getContainerid()
489     {
490         return(id.getContainerId());
491     }
492
493     /**
494      * Return dynamic information about the conglomerate to be dynamically
495      * reused in repeated execution of a statement.
496      * <p>
497      * The dynamic info is a set of variables to be used in a given
498      * ScanController or ConglomerateController. It can only be used in one
499      * controller at a time. It is up to the caller to insure the correct
500      * thread access to this info. The type of info in this is a scratch
501      * template for btree traversal, other scratch variables for qualifier
502      * evaluation, ...
503      * <p>
504      *
505      * @return The dynamic information.
506      *
507      * @param conglomId The identifier of the conglomerate to open.
508      *
509      * @exception StandardException Standard exception policy.
510      **/

511     public DynamicCompiledOpenConglomInfo getDynamicCompiledConglomInfo(
512     long conglomId)
513         throws StandardException
514     {
515         return(new OpenConglomerateScratchSpace(format_ids));
516     }
517
518     /**
519      * Return static information about the conglomerate to be included in a
520      * a compiled plan.
521      * <p>
522      * The static info would be valid until any ddl was executed on the
523      * conglomid, and would be up to the caller to throw away when that
524      * happened. This ties in with what language already does for other
525      * invalidation of static info. The type of info in this would be
526      * containerid and array of format id's from which templates can be created.
527      * The info in this object is read only and can be shared among as many
528      * threads as necessary.
529      * <p>
530      *
531      * @return The static compiled information.
532      *
533      * @param conglomId The identifier of the conglomerate to open.
534      *
535      * @exception StandardException Standard exception policy.
536      **/

537     public StaticCompiledOpenConglomInfo getStaticCompiledConglomInfo(
538     TransactionController tc,
539     long conglomId)
540         throws StandardException
541     {
542         return(this);
543     }
544
545
546     /**
547      * Is this conglomerate temporary?
548      * <p>
549      *
550      * @return whether conglomerate is temporary or not.
551      **/

552     public boolean isTemporary()
553     {
554         return(id.getSegmentId() == ContainerHandle.TEMPORARY_SEGMENT);
555     }
556
557
558     /**
559      * Bulk load into the conglomerate.
560      * <p>
561      *
562      * @see Conglomerate#load
563      *
564      * @exception StandardException Standard exception policy.
565      **/

566     public long load(
567     TransactionManager xact_manager,
568     boolean createConglom,
569     RowLocationRetRowSource rowSource)
570          throws StandardException
571     {
572         long num_rows_loaded = 0;
573
574         HeapController heapcontroller = new HeapController();
575
576         try
577         {
578             num_rows_loaded =
579                 heapcontroller.load(
580                     xact_manager,
581                     this,
582                     createConglom,
583                     rowSource);
584         }
585         finally
586         {
587             // Done with this heap controller.
588
heapcontroller.close();
589         }
590
591         return(num_rows_loaded);
592     }
593
594     /**
595      * Open a heap controller.
596      * <p>
597      *
598      * @see Conglomerate#open
599      *
600      * @exception StandardException Standard exception policy.
601      **/

602     public ConglomerateController open(
603     TransactionManager xact_manager,
604     Transaction rawtran,
605     boolean hold,
606     int open_mode,
607     int lock_level,
608     LockingPolicy locking_policy,
609     StaticCompiledOpenConglomInfo static_info,
610     DynamicCompiledOpenConglomInfo dynamic_info)
611         throws StandardException
612     {
613         OpenConglomerate open_conglom = new OpenHeap();
614
615         if (open_conglom.init(
616                 (ContainerHandle) null,
617                 this,
618                 this.format_ids,
619                 xact_manager,
620                 rawtran,
621                 hold,
622                 open_mode,
623                 lock_level,
624                 locking_policy,
625                 dynamic_info) == null)
626         {
627             throw StandardException.newException(
628                     SQLState.HEAP_CONTAINER_NOT_FOUND,
629                     new Long JavaDoc(id.getContainerId()).toString());
630         }
631
632         HeapController heapcontroller = new HeapController();
633
634         heapcontroller.init(open_conglom);
635
636         return(heapcontroller);
637     }
638
639     /**
640      * Open a heap scan controller.
641      * <p>
642      *
643      * @see Conglomerate#openScan
644      *
645      * @exception StandardException Standard exception policy.
646      **/

647     public ScanManager openScan(
648     TransactionManager xact_manager,
649     Transaction rawtran,
650     boolean hold,
651     int open_mode,
652     int lock_level,
653     LockingPolicy locking_policy,
654     int isolation_level,
655     FormatableBitSet scanColumnList,
656     DataValueDescriptor[] startKeyValue,
657     int startSearchOperator,
658     Qualifier qualifier[][],
659     DataValueDescriptor[] stopKeyValue,
660     int stopSearchOperator,
661     StaticCompiledOpenConglomInfo static_info,
662     DynamicCompiledOpenConglomInfo dynamic_info)
663         throws StandardException
664     {
665         // Heap scans do not suppport start and stop scan positions (these
666
// only make sense for ordered storage structures).
667
if (!RowUtil.isRowEmpty(startKeyValue)
668             || !RowUtil.isRowEmpty(stopKeyValue))
669         {
670             throw StandardException.newException(
671                     SQLState.HEAP_UNIMPLEMENTED_FEATURE);
672         }
673
674         OpenConglomerate open_conglom = new OpenHeap();
675
676         if (open_conglom.init(
677                 (ContainerHandle) null,
678                 this,
679                 this.format_ids,
680                 xact_manager,
681                 rawtran,
682                 hold,
683                 open_mode,
684                 lock_level,
685                 locking_policy,
686                 dynamic_info) == null)
687         {
688             throw StandardException.newException(
689                     SQLState.HEAP_CONTAINER_NOT_FOUND,
690                     new Long JavaDoc(id.getContainerId()));
691         }
692
693         HeapScan heapscan = new HeapScan();
694
695         heapscan.init(
696             open_conglom,
697             scanColumnList,
698             startKeyValue,
699             startSearchOperator,
700             qualifier,
701             stopKeyValue,
702             stopSearchOperator);
703
704         return(heapscan);
705     }
706
707     public void purgeConglomerate(
708     TransactionManager xact_manager,
709     Transaction rawtran)
710         throws StandardException
711     {
712         OpenConglomerate open_for_ddl_lock = null;
713         HeapController heapcontroller = null;
714         TransactionManager nested_xact = null;
715
716         try
717         {
718             open_for_ddl_lock = new OpenHeap();
719
720             // Open table in intended exclusive mode in the top level
721
// transaction, this will stop any ddl from happening until
722
// purge of whole table is finished.
723

724             if (open_for_ddl_lock.init(
725                     (ContainerHandle) null,
726                     this,
727                     this.format_ids,
728                     xact_manager,
729                     rawtran,
730                     false,
731                     TransactionController.OPENMODE_FORUPDATE,
732                     TransactionController.MODE_RECORD,
733                     null,
734                     null) == null)
735             {
736                 throw StandardException.newException(
737                         SQLState.HEAP_CONTAINER_NOT_FOUND,
738                         new Long JavaDoc(id.getContainerId()));
739             }
740
741             // perform all the "real" work in a non-readonly nested user
742
// transaction, so that as work is completed on each page resources
743
// can be released. Must be careful as all locks obtained in nested
744
// transaction will conflict with parent transaction - so this call
745
// must be made only if parent transaction can have no conflicting
746
// locks on the table, otherwise the purge will fail with a self
747
// deadlock.
748
nested_xact = (TransactionManager)
749                 xact_manager.startNestedUserTransaction(false);
750
751             // now open the table in a nested user transaction so that each
752
// page worth of work can be committed after it is done.
753

754             OpenConglomerate open_conglom = new OpenHeap();
755
756             if (open_conglom.init(
757                 (ContainerHandle) null,
758                 this,
759                 this.format_ids,
760                 nested_xact,
761                 nested_xact.getRawStoreXact(),
762                 true,
763                 TransactionController.OPENMODE_FORUPDATE,
764                 TransactionController.MODE_RECORD,
765                 nested_xact.getRawStoreXact().newLockingPolicy(
766                     LockingPolicy.MODE_RECORD,
767                         TransactionController.ISOLATION_REPEATABLE_READ, true),
768                 null) == null)
769             {
770                 throw StandardException.newException(
771                         SQLState.HEAP_CONTAINER_NOT_FOUND,
772                         new Long JavaDoc(id.getContainerId()).toString());
773             }
774
775             heapcontroller = new HeapController();
776
777             heapcontroller.init(open_conglom);
778
779             Page page = open_conglom.getContainer().getFirstPage();
780
781             boolean purgingDone = false;
782
783             while (page != null)
784             {
785                 long pageno = page.getPageNumber();
786                 purgingDone = heapcontroller.purgeCommittedDeletes(page);
787
788                 if (purgingDone)
789                 {
790                     page = null;
791
792                     // commit xact to free resouurces ASAP, commit will
793
// unlatch the page if it has not already been unlatched
794
// by a remove.
795
open_conglom.getXactMgr().commitNoSync(
796                                 TransactionController.RELEASE_LOCKS);
797
798                     // the commit closes the underlying container, so let
799
// the heapcontroller know this has happened. Usually
800
// the transaction takes care of this, but this controller
801
// is internal, so the transaction does not know about it.
802
heapcontroller.closeForEndTransaction(false);
803                     
804                     // the commit will close the underlying
805
open_conglom.reopen();
806                 }
807                 else
808                 {
809                     page.unlatch();
810                     page = null;
811                 }
812
813                 page = open_conglom.getContainer().getNextPage(pageno);
814             }
815         }
816         finally
817         {
818             if (open_for_ddl_lock != null)
819                 open_for_ddl_lock.close();
820             if (heapcontroller != null)
821                 heapcontroller.close();
822             if (nested_xact != null)
823             {
824                 nested_xact.commitNoSync(TransactionController.RELEASE_LOCKS);
825                 nested_xact.destroy();
826             }
827         }
828
829         return;
830     }
831
832     public void compressConglomerate(
833     TransactionManager xact_manager,
834     Transaction rawtran)
835         throws StandardException
836     {
837         OpenConglomerate open_conglom = null;
838         HeapController heapcontroller = null;
839
840         try
841         {
842             open_conglom = new OpenHeap();
843
844             // Open table in intended exclusive mode in the top level
845
// transaction, this will stop any ddl from happening until
846
// purge of whole table is finished.
847

848             if (open_conglom.init(
849                     (ContainerHandle) null,
850                     this,
851                     this.format_ids,
852                     xact_manager,
853                     rawtran,
854                     false,
855                     TransactionController.OPENMODE_FORUPDATE,
856                     TransactionController.MODE_TABLE,
857                     rawtran.newLockingPolicy(
858                         LockingPolicy.MODE_CONTAINER,
859                         TransactionController.ISOLATION_REPEATABLE_READ, true),
860                     null) == null)
861             {
862                 throw StandardException.newException(
863                         SQLState.HEAP_CONTAINER_NOT_FOUND,
864                         new Long JavaDoc(id.getContainerId()));
865             }
866
867             heapcontroller = new HeapController();
868
869             heapcontroller.init(open_conglom);
870
871             open_conglom.getContainer().compressContainer();
872         }
873         finally
874         {
875             if (open_conglom != null)
876                 open_conglom.close();
877         }
878
879         return;
880     }
881
882     /**
883      * Open a heap compress scan.
884      * <p>
885      *
886      * @see Conglomerate#defragmentConglomerate
887      *
888      * @exception StandardException Standard exception policy.
889      **/

890     public ScanManager defragmentConglomerate(
891     TransactionManager xact_manager,
892     Transaction rawtran,
893     boolean hold,
894     int open_mode,
895     int lock_level,
896     LockingPolicy locking_policy,
897     int isolation_level)
898         throws StandardException
899     {
900         OpenConglomerate open_conglom = new OpenHeap();
901
902         if (open_conglom.init(
903                 (ContainerHandle) null,
904                 this,
905                 this.format_ids,
906                 xact_manager,
907                 rawtran,
908                 hold,
909                 open_mode,
910                 lock_level,
911                 rawtran.newLockingPolicy(
912                     LockingPolicy.MODE_RECORD,
913                     TransactionController.ISOLATION_REPEATABLE_READ, true),
914                 null) == null)
915         {
916             throw StandardException.newException(
917                     SQLState.HEAP_CONTAINER_NOT_FOUND,
918                     new Long JavaDoc(id.getContainerId()));
919         }
920
921         HeapCompressScan heap_compress_scan = new HeapCompressScan();
922
923         heap_compress_scan.init(
924             open_conglom,
925             null,
926             null,
927             0,
928             null,
929             null,
930             0);
931
932         return(heap_compress_scan);
933     }
934
935
936     /**
937      * Return an open StoreCostController for the conglomerate.
938      * <p>
939      * Return an open StoreCostController which can be used to ask about
940      * the estimated row counts and costs of ScanController and
941      * ConglomerateController operations, on the given conglomerate.
942      * <p>
943      * @param xact_manager The TransactionController under which this
944      * operation takes place.
945      * @param rawtran raw transaction context in which scan is managed.
946      *
947      * @return The open StoreCostController.
948      *
949      * @exception StandardException Standard exception policy.
950      *
951      * @see StoreCostController
952      **/

953     public StoreCostController openStoreCost(
954     TransactionManager xact_manager,
955     Transaction rawtran)
956         throws StandardException
957     {
958         OpenHeap open_conglom = new OpenHeap();
959
960         if (open_conglom.init(
961                 (ContainerHandle) null,
962                 this,
963                 this.format_ids,
964                 xact_manager,
965                 rawtran,
966                 false,
967                 ContainerHandle.MODE_READONLY,
968                 TransactionController.MODE_TABLE,
969                 (LockingPolicy) null,
970                 (DynamicCompiledOpenConglomInfo) null) == null)
971         {
972             throw StandardException.newException(
973                     SQLState.HEAP_CONTAINER_NOT_FOUND,
974                     new Long JavaDoc(id.getContainerId()));
975         }
976
977
978         HeapCostController heapcost = new HeapCostController();
979
980         heapcost.init(open_conglom);
981
982         return(heapcost);
983     }
984
985
986     /**
987      * Print this heap.
988      **/

989     public String JavaDoc toString()
990     {
991         return (id == null) ? "null" : id.toString();
992     }
993
994     /**************************************************************************
995      * Public Methods of StaticCompiledOpenConglomInfo Interface:
996      **************************************************************************
997      */

998
999     /**
1000     * return the "Conglomerate".
1001     * <p>
1002     * For heap just return "this", which both implements Conglomerate and
1003     * StaticCompiledOpenConglomInfo.
1004     * <p>
1005     *
1006     * @return this
1007     **/

1008    public DataValueDescriptor getConglom()
1009    {
1010        return(this);
1011    }
1012
1013
1014    /**************************************************************************
1015     * Methods of Storable (via Conglomerate)
1016     * Storable interface, implies Externalizable, TypedFormat
1017     **************************************************************************
1018     */

1019
1020    /**
1021     * Return my format identifier.
1022     *
1023     * @see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId
1024     **/

1025    public int getTypeFormatId()
1026    {
1027        return StoredFormatIds.ACCESS_HEAP_V2_ID;
1028    }
1029
1030    /**
1031     * Return whether the value is null or not.
1032     *
1033     * @see org.apache.derby.iapi.services.io.Storable#isNull
1034     **/

1035    public boolean isNull()
1036    {
1037        return id == null;
1038    }
1039
1040    /**
1041     * Restore the in-memory representation to the null value.
1042     *
1043     * @see org.apache.derby.iapi.services.io.Storable#restoreToNull
1044     *
1045     **/

1046    public void restoreToNull()
1047    {
1048        id = null;
1049    }
1050
1051    /**
1052     * Store the stored representation of the column value in the stream.
1053     *
1054     **/

1055    public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc
1056    {
1057
1058        // write the format id of this conglomerate
1059
FormatIdUtil.writeFormatIdInteger(out, this.getTypeFormatId());
1060
1061        out.writeInt((int) id.getSegmentId());
1062        out.writeLong(id.getContainerId());
1063
1064        // write number of columns in heap.
1065
out.writeInt(format_ids.length);
1066
1067        // write out array of format id's
1068
ConglomerateUtil.writeFormatIdArray(format_ids, out);
1069    }
1070
1071    /**
1072     * Restore the in-memory representation from the stream.
1073     *
1074     * @see java.io.Externalizable#readExternal
1075     **/

1076    public void readExternal(ObjectInput JavaDoc in) throws IOException JavaDoc
1077    {
1078        // read the format id of this conglomerate.
1079
FormatIdUtil.readFormatIdInteger(in);
1080
1081        int segmentid = in.readInt();
1082        long containerid = in.readLong();
1083
1084        id = new ContainerKey(segmentid, containerid);
1085
1086        // read the number of columns in the heap.
1087
int num_columns = in.readInt();
1088
1089        // read the array of format ids.
1090
format_ids = ConglomerateUtil.readFormatIdArray(num_columns, in);
1091    }
1092
1093    public void readExternalFromArray(ArrayInputStream in) throws IOException JavaDoc
1094    {
1095        // read the format id of this conglomerate.
1096
FormatIdUtil.readFormatIdInteger(in);
1097
1098        int segmentid = in.readInt();
1099        long containerid = in.readLong();
1100
1101        id = new ContainerKey(segmentid, containerid);
1102
1103        // read the number of columns in the heap.
1104
int num_columns = in.readInt();
1105
1106        // read the array of format ids.
1107
format_ids = ConglomerateUtil.readFormatIdArray(num_columns, in);
1108    }
1109
1110}
1111
Popular Tags