KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > store > access > btree > index > B2I


1 /*
2
3    Derby - Class org.apache.derby.impl.store.access.btree.index.B2I
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.btree.index;
23
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 import org.apache.derby.iapi.error.StandardException;
37 import org.apache.derby.iapi.store.access.conglomerate.Conglomerate;
38 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
39 import org.apache.derby.iapi.store.access.conglomerate.ScanManager;
40 import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;
41 import org.apache.derby.iapi.store.access.ConglomerateController;
42 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo;
43 import org.apache.derby.iapi.store.access.Qualifier;
44 import org.apache.derby.iapi.types.RowLocation;
45 import org.apache.derby.iapi.store.access.RowLocationRetRowSource;
46 import org.apache.derby.iapi.store.access.ScanController;
47 import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo;
48 import org.apache.derby.iapi.store.access.StoreCostController;
49 import org.apache.derby.iapi.store.access.TransactionController;
50 import org.apache.derby.iapi.store.access.ColumnOrdering;
51
52 import org.apache.derby.iapi.services.io.FormatIdUtil;
53 import org.apache.derby.iapi.services.io.StoredFormatIds;
54
55 import org.apache.derby.iapi.store.raw.ContainerHandle;
56 import org.apache.derby.iapi.store.raw.LockingPolicy;
57 import org.apache.derby.iapi.store.raw.Page;
58 import org.apache.derby.iapi.store.raw.RecordHandle;
59 import org.apache.derby.iapi.store.raw.Transaction;
60
61 import org.apache.derby.iapi.types.DataValueDescriptor;
62
63 import org.apache.derby.impl.store.access.btree.BTree;
64 import org.apache.derby.impl.store.access.btree.BTreeLockingPolicy;
65 import org.apache.derby.impl.store.access.btree.LeafControlRow;
66 import org.apache.derby.impl.store.access.btree.ControlRow;
67 import org.apache.derby.impl.store.access.btree.OpenBTree;
68 import org.apache.derby.impl.store.access.btree.WaitError;
69
70 import org.apache.derby.impl.store.access.conglomerate.ConglomerateUtil;
71 import org.apache.derby.iapi.services.io.FormatableBitSet;
72 import org.apache.derby.iapi.services.cache.ClassSize;
73
74 /*
75  * @format_id ACCESS_B2I_V1_ID
76  *
77  * @purpose The tag that describes the on disk representation of the B2I
78  * conglomerate object. The B2I conglomerate object is stored in
79  * a field of a row in the Conglomerate directory.
80  *
81  * @upgrade This format was made obsolete in the kimono release.
82  *
83  * @disk_layout
84  * containerid(long)
85  * segmentid(int)
86  * number_of_key_fields(int)
87  * number_of_unique_columns(int)
88  * allow_duplicates(boolean)
89  * maintain_parent_links(boolean)
90  * format_of_this_conlgomerate(byte[])
91  * array_of_format_ids(byte[][])
92  * baseConglomerateId(long)
93  * rowLocationColumn(int)
94  */

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

125
126 /**
127  * Implements an instance of a B-Tree secondary index conglomerate.
128  * A B2I object has two roles.
129  * <ol>
130  * <li>
131  * The B2I object is stored on disk, and holds the store specific
132  * information needed to access/describe the conglomerate. This
133  * includes information such as the format ids of the columns,
134  * the conglomerate id of the base table, the location of
135  * row location column.
136  * </li>
137  * <li>
138  * Access to all the interfaces start by making a call off the
139  * Conglomerate interface. So for instance to get a scan on the
140  * conglomerate method {@link #openScan openScan} should be called.
141  * </li>
142  * </ol>
143  */

144 public class B2I extends BTree
145 {
146     public static final String JavaDoc PROPERTY_BASECONGLOMID = "baseConglomerateId";
147     public static final String JavaDoc PROPERTY_ROWLOCCOLUMN = "rowLocationColumn";
148
149     public static final int FORMAT_NUMBER = StoredFormatIds.ACCESS_B2I_V3_ID;
150
151     /*
152     ** Fields of B2I.
153     */

154
155     /**
156     The id of the conglomerate which contains the base table.
157     Row locations inserted into this secondary index are assumed
158     to refer to that conglomerate. Used to obtain table/row locks on the
159     base table rows which the index rows point at.
160     **/

161     protected long baseConglomerateId;
162
163     /**
164     The column id (zero-based integer index) of the column which holds the row
165     location to the base conglomerate.
166     The default value of RowLocationColumn is the last key column.
167     Used to obtain table/row locks on the base table rows with the index rows
168     point at.
169     Currently, RowLocationColumn must be the last key column.
170     **/

171     protected int rowLocationColumn;
172
173     private static final int BASE_MEMORY_USAGE = ClassSize.estimateBaseFromCatalog( B2I.class);
174
175     public int estimateMemoryUsage()
176     {
177         return BASE_MEMORY_USAGE;
178     }
179
180     /**************************************************************************
181      * Constructors for This class:
182      **************************************************************************
183      */

184
185     /**************************************************************************
186      * Protected locking implmentations of abtract BTree routines:
187      * getBtreeLockingPolicy
188      * lockTable
189      **************************************************************************
190      */

191
192     /**
193      * Create a new btree locking policy from scratch.
194      *
195      * @exception StandardException Standard exception policy.
196      **/

197     protected BTreeLockingPolicy getBtreeLockingPolicy(
198     Transaction rawtran,
199     int lock_level,
200     int mode,
201     int isolation_level,
202     ConglomerateController base_cc,
203     OpenBTree open_btree)
204         throws StandardException
205     {
206         BTreeLockingPolicy ret_locking_policy = null;
207
208         if (SanityManager.DEBUG)
209         {
210             SanityManager.ASSERT(
211                 (isolation_level ==
212                      TransactionController.ISOLATION_SERIALIZABLE) ||
213                 (isolation_level ==
214                      TransactionController.ISOLATION_REPEATABLE_READ) ||
215                 (isolation_level ==
216                      TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK) ||
217                 (isolation_level ==
218                      TransactionController.ISOLATION_READ_COMMITTED) ||
219                 (isolation_level ==
220                      TransactionController.ISOLATION_READ_UNCOMMITTED),
221                 "bad isolation_level = " + isolation_level);
222         }
223
224         if (lock_level == TransactionController.MODE_TABLE)
225         {
226             ret_locking_policy =
227                 new B2ITableLocking3(
228                     rawtran,
229                     lock_level,
230                     rawtran.newLockingPolicy(
231                         LockingPolicy.MODE_CONTAINER,
232                         isolation_level,
233                         true),
234                     base_cc,
235                     open_btree);
236         }
237         else if (lock_level == TransactionController.MODE_RECORD)
238         {
239             if (isolation_level == TransactionController.ISOLATION_SERIALIZABLE)
240             {
241                 ret_locking_policy =
242                     new B2IRowLocking3(
243                         rawtran,
244                         lock_level,
245                         rawtran.newLockingPolicy(
246                             LockingPolicy.MODE_RECORD,
247                             isolation_level,
248                             true),
249                         base_cc,
250                         open_btree);
251             }
252             else if ((isolation_level ==
253                         TransactionController.ISOLATION_REPEATABLE_READ))
254             {
255                 ret_locking_policy =
256                     new B2IRowLockingRR(
257                         rawtran,
258                         lock_level,
259                         rawtran.newLockingPolicy(
260                             LockingPolicy.MODE_RECORD,
261                             isolation_level,
262                             true),
263                         base_cc,
264                         open_btree);
265             }
266             else if ((isolation_level ==
267                         TransactionController.ISOLATION_READ_COMMITTED) ||
268                      (isolation_level ==
269                         TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK))
270             {
271                 ret_locking_policy =
272                     new B2IRowLocking2(
273                         rawtran,
274                         lock_level,
275                         rawtran.newLockingPolicy(
276                             LockingPolicy.MODE_RECORD,
277                             isolation_level,
278                             true),
279                         base_cc,
280                         open_btree);
281             }
282             else if (isolation_level ==
283                         TransactionController.ISOLATION_READ_UNCOMMITTED)
284             {
285                 ret_locking_policy =
286                     new B2IRowLocking1(
287                         rawtran,
288                         lock_level,
289                         rawtran.newLockingPolicy(
290                             LockingPolicy.MODE_RECORD,
291                             isolation_level,
292                             true),
293                         base_cc,
294                         open_btree);
295             }
296         }
297
298
299         if (SanityManager.DEBUG)
300         {
301             SanityManager.ASSERT(
302                 ret_locking_policy != null, "ret_locking_policy == null");
303         }
304
305         return(ret_locking_policy);
306     }
307
308     /**
309      * Lock the base table.
310      * <p>
311      * Assumes that segment of the base container is the same as the segment
312      * of the btree segment.
313      * <p>
314      * RESOLVE - we really want to get the lock without opening the container.
315      * raw store will be providing this.
316      *
317      * @param xact_manager Transaction to associate the lock with.
318      *
319      * @exception StandardException Standard exception policy.
320      **/

321     public final ConglomerateController lockTable(
322     TransactionManager xact_manager,
323     int open_mode,
324     int lock_level,
325     int isolation_level)
326         throws StandardException
327     {
328         open_mode |= TransactionController.OPENMODE_FOR_LOCK_ONLY;
329
330         // open the base conglomerate - just to get the table lock.
331
ConglomerateController cc =
332             xact_manager.openConglomerate(
333                 this.baseConglomerateId, false, open_mode, lock_level,
334                 isolation_level);
335
336         return(cc);
337     }
338
339     /**************************************************************************
340      * Private methods of B2I, arranged alphabetically.
341      **************************************************************************
342      */

343
344
345     private void traverseRight()
346     {
347         // RESOLVE - Do I have to do this???????????????
348

349         if (SanityManager.DEBUG)
350             SanityManager.THROWASSERT("not implemented.");
351     }
352
353
354     /*
355     ** Methods of B2I.
356     */

357
358     /**
359     Create an empty secondary index b-tree, using the generic b-tree to do the
360     generic part of the creation process.
361
362     This routine opens the newly created container, adds a single page, and
363     makes this page the root by inserting a LeafControlRow onto this page
364     at slot 0 and marking in that control row that the page is a root page.
365
366     The following properties are specific to the b-tree secondary index:
367     <UL>
368     <LI> "baseConglomerateId" (integer). The conglomerate id of the base
369     conglomerate is never actually accessed by the b-tree secondary
370     index implementation, it only serves as a namespace for row locks.
371     This property is required.
372     <LI> "rowLocationColumn" (integer). The zero-based index into the row which
373     the b-tree secondary index will assume holds a @see RowLocation of
374     the base row in the base conglomerate. This value will be used
375     for acquiring locks. In this implementation RowLocationColumn must be
376     the last key column.
377     This property is required.
378     </UL>
379
380     A secondary index i (a, b) on table t (a, b, c) would have rows
381     which looked like (a, b, row_location). baseConglomerateId is set to the
382     conglomerate id of t. rowLocationColumns is set to 2. allowsDuplicates
383     would be set to false, @see BTree#create. To create a unique
384     secondary index set uniquenessColumns to 2, this means that the btree
385     code will compare the key values but not the row id when determing
386     uniqueness. To create a nonunique secondary index set uniquenessColumns
387     to 3, this would mean that the uniqueness test would include the row
388     location and since all row locations will be unique all rows inserted
389     into the index will be differentiated (at least) by row location.
390
391     @see BTree#create
392
393     @exception StandardException Standard exception policy.
394     **/

395     public void create(
396     TransactionManager xact_manager,
397     int segmentId,
398     long input_conglomid,
399     DataValueDescriptor[] template,
400     ColumnOrdering[] columnOrder,
401     Properties JavaDoc properties,
402     int temporaryFlag)
403         throws StandardException
404     {
405         String JavaDoc property_value = null;
406         Transaction rawtran = xact_manager.getRawStoreXact();
407
408         if (properties == null)
409         {
410             throw(StandardException.newException(
411                     SQLState.BTREE_PROPERTY_NOT_FOUND, PROPERTY_BASECONGLOMID));
412         }
413
414         // Get baseConglomerateId //
415
property_value = properties.getProperty(PROPERTY_BASECONGLOMID);
416         if (property_value == null)
417         {
418             throw(StandardException.newException(
419                     SQLState.BTREE_PROPERTY_NOT_FOUND, PROPERTY_BASECONGLOMID));
420         }
421
422         if (SanityManager.DEBUG)
423         {
424             if (property_value == null)
425                 SanityManager.THROWASSERT(
426                     PROPERTY_BASECONGLOMID +
427                     "property not passed to B2I.create()");
428         }
429
430         baseConglomerateId = Long.parseLong(property_value);
431
432         // Get rowLocationColumn //
433
property_value = properties.getProperty(PROPERTY_ROWLOCCOLUMN);
434
435         if (SanityManager.DEBUG)
436         {
437             if (property_value == null)
438                 SanityManager.THROWASSERT(
439                     PROPERTY_ROWLOCCOLUMN +
440                     "property not passed to B2I.create()");
441         }
442
443         if (property_value == null)
444         {
445             throw(StandardException.newException(
446                     SQLState.BTREE_PROPERTY_NOT_FOUND, PROPERTY_BASECONGLOMID));
447         }
448
449         rowLocationColumn = Integer.parseInt(property_value);
450
451         // Currently the row location column must be the last column (makes)
452
// comparing the columns in the index easier.
453
if (SanityManager.DEBUG)
454         {
455             SanityManager.ASSERT(rowLocationColumn == template.length - 1,
456                 "rowLocationColumn is not the last column in the index");
457             SanityManager.ASSERT(
458                 template[rowLocationColumn] instanceof
459                     RowLocation);
460
461             // There must be at least one key column
462
if (rowLocationColumn < 1)
463                 SanityManager.THROWASSERT(
464                     "rowLocationColumn (" + rowLocationColumn +
465                     ") expected to be >= 1");
466         }
467
468
469         /* covert the sorting order information into a boolean array map.
470          * If the sorting order for the columns is not provided, we
471          * assign the default as Ascending Order.
472          * array length is equla to template length , because column order
473          * length changes wther it is unique is non unique. store assumes
474          * template length arrays. So , we make template length array and make
475          * the last column as ascending instead of having lot of execeptions code.
476          */

477         
478         ascDescInfo = new boolean[template.length];
479         for (int i=0 ; i < ascDescInfo.length; i++)
480         {
481             if (columnOrder != null && i < columnOrder.length)
482                 ascDescInfo[i] = columnOrder[i].getIsAscending();
483             else
484                 ascDescInfo[i] = true; // default values - ascending order
485
}
486
487         // Do the generic part of creating the b-tree.
488
super.create(rawtran, segmentId, input_conglomid, template, properties, getTypeFormatId(), temporaryFlag);
489
490         // open the base conglomerate - to get the lock
491
ConglomerateController base_cc =
492             xact_manager.openConglomerate(
493                 baseConglomerateId,
494                 false,
495                 TransactionController.OPENMODE_FOR_LOCK_ONLY,
496                 TransactionController.MODE_TABLE,
497                 TransactionController.ISOLATION_SERIALIZABLE);
498         
499         OpenBTree open_btree = new OpenBTree();
500
501         BTreeLockingPolicy b2i_locking_policy =
502             new B2ITableLocking3(
503                 rawtran,
504                 TransactionController.MODE_TABLE,
505                 rawtran.newLockingPolicy(
506                     LockingPolicy.MODE_CONTAINER,
507                     TransactionController.ISOLATION_SERIALIZABLE, true), base_cc, open_btree);
508
509
510         // The following call will "open" the new btree. Create is
511
// an interesting case. What we really want is read only table lock
512
// on the base conglomerate and update locks on the index. For now
513
// just get the update lock on the base table, this is done by the
514
// lockTable() call made by base class.
515

516         open_btree.init(
517             (TransactionManager) xact_manager, // current user xact
518
(TransactionManager) xact_manager, // current xact
519
(ContainerHandle) null, // have init open the container.
520
rawtran,
521             false,
522             (ContainerHandle.MODE_FORUPDATE),
523             TransactionController.MODE_TABLE,
524             b2i_locking_policy, // get table level lock.
525
this,
526             (LogicalUndo) null, // no logical undo necessary, as
527
// initEmptyBtree()
528
// work will be done single user and
529
// rows will not move.
530
(DynamicCompiledOpenConglomInfo) null);
531                                         
532         // Open the newly created container, and insert the first control row.
533
LeafControlRow.initEmptyBtree(open_btree);
534
535         open_btree.close();
536
537         base_cc.close();
538     }
539
540
541
542     /*
543     ** Methods of Conglomerate
544     */

545
546     /**
547      * Retrieve the maximum value row in an ordered conglomerate.
548      * <p>
549      * Returns true and fetches the rightmost row of an ordered conglomerate
550      * into "fetchRow" if there is at least one row in the conglomerate. If
551      * there are no rows in the conglomerate it returns false.
552      * <p>
553      * Non-ordered conglomerates will not implement this interface, calls
554      * will generate a StandardException.
555      * <p>
556      * RESOLVE - this interface is temporary, long term equivalent (and more)
557      * functionality will be provided by the openBackwardScan() interface.
558      *
559      * @param xact_manager The TransactionController under which this
560      * operation takes place.
561      *
562      * @param conglomId The identifier of the conglomerate
563      * to open the scan for.
564      *
565      * @param open_mode Specifiy flags to control opening of table.
566      * OPENMODE_FORUPDATE - if set open the table for
567      * update otherwise open table shared.
568      * @param lock_level One of (MODE_TABLE, MODE_RECORD, or MODE_NONE).
569      *
570      * @param isolation_level The isolation level to lock the conglomerate at.
571      * One of (ISOLATION_READ_COMMITTED or ISOLATION_SERIALIZABLE).
572      *
573      * @param scanColumnList A description of which columns to return from
574      * every fetch in the scan. template,
575      * and scanColumnList work together
576      * to describe the row to be returned by the scan -
577      * see RowUtil for description of how these three
578      * parameters work together to describe a "row".
579      *
580      * @param fetchRow The row to retrieve the maximum value into.
581      *
582      * @return boolean indicating if a row was found and retrieved or not.
583      *
584      * @exception StandardException Standard exception policy.
585      **/

586     public boolean fetchMaxOnBTree(
587     TransactionManager xact_manager,
588     Transaction rawtran,
589     long conglomId,
590     int open_mode,
591     int lock_level,
592     LockingPolicy locking_policy,
593     int isolation_level,
594     FormatableBitSet scanColumnList,
595     DataValueDescriptor[] fetchRow)
596         throws StandardException
597     {
598         boolean row_exists;
599
600         // row level locking implementation.
601

602         // RESOLVE (revisit implementation after all the Xena rowlocking
603
// changes have been made). Can probably come up with single
604
// path implementation.
605

606         // Create a new b-tree secondary index scan.
607
B2IMaxScan b2is = new B2IMaxScan();
608
609         // Initialize it.
610
b2is.init(
611             xact_manager,
612             rawtran,
613             open_mode,
614             lock_level,
615             locking_policy,
616             isolation_level,
617             true /* get locks on base table as part of open */,
618             scanColumnList,
619             this,
620             new B2IUndo());
621
622         row_exists = b2is.fetchMax(fetchRow);
623
624         b2is.close();
625
626         return(row_exists);
627     }
628
629
630     /**
631     Bulk Load a B-tree secondary index.
632
633     @see Conglomerate#load
634     @exception StandardException Standard Cloudscape Error policy.
635     raise SQLState.STORE_CONGLOMERATE_DUPLICATE_KEY_EXCEPTION if a duplicate
636     key is detected in the load.
637     **/

638
639     public long load(
640     TransactionManager xact_manager,
641     boolean createConglom,
642     RowLocationRetRowSource rowSource)
643          throws StandardException
644     {
645         long num_rows_loaded = 0;
646         B2IController b2ic = new B2IController();
647
648         try
649         {
650             int open_mode = TransactionController.OPENMODE_FORUPDATE;
651
652             if (createConglom)
653             {
654                 open_mode |=
655                     (ContainerHandle.MODE_UNLOGGED |
656                      ContainerHandle.MODE_CREATE_UNLOGGED);
657             }
658
659             // Do the actual open of the container in the super class.
660
b2ic.init(
661                 xact_manager, // current transaction
662
xact_manager.getRawStoreXact(), // current raw store xact
663
false, // Not holdable
664
open_mode,
665                 TransactionController.MODE_TABLE,
666                 xact_manager.getRawStoreXact().newLockingPolicy(
667                     LockingPolicy.MODE_CONTAINER,
668                     TransactionController.ISOLATION_SERIALIZABLE, true),
669                 true,
670                 this,
671                 new B2IUndo(),
672                 (B2IStaticCompiledInfo) null,
673                 (DynamicCompiledOpenConglomInfo) null);
674
675             num_rows_loaded = b2ic.load(xact_manager, createConglom, rowSource);
676
677         }
678         finally
679         {
680             b2ic.close();
681         }
682
683         return(num_rows_loaded);
684     }
685
686     /**
687     Open a b-tree controller.
688     @see Conglomerate#open
689
690     @exception StandardException Standard exception policy.
691     **/

692     public ConglomerateController open(
693     TransactionManager xact_manager,
694     Transaction rawtran,
695     boolean hold,
696     int open_mode,
697     int lock_level,
698     LockingPolicy locking_policy,
699     StaticCompiledOpenConglomInfo static_info,
700     DynamicCompiledOpenConglomInfo dynamic_info)
701         throws StandardException
702     {
703         // Create a new b-tree secondary index controller.
704
B2IController b2ic = new B2IController();
705
706         // Do the actual open of the container in the super class.
707
b2ic.init(
708             xact_manager, // current transaction
709
rawtran, // current raw store transaction
710
hold, // holdability
711
open_mode,
712             lock_level,
713             locking_policy,
714             true,
715             this,
716             new B2IUndo(),
717             (B2IStaticCompiledInfo) static_info,
718             dynamic_info);
719
720         // Return it to the caller.
721
return b2ic;
722     }
723
724     /**
725     Open a b-tree secondary index scan controller.
726     @see Conglomerate#openScan
727     @see BTree#openScan
728
729     @exception StandardException Standard exception policy.
730     **/

731     public ScanManager openScan(
732     TransactionManager xact_manager,
733     Transaction rawtran,
734     boolean hold,
735     int open_mode,
736     int lock_level,
737     LockingPolicy locking_policy,
738     int isolation_level,
739     FormatableBitSet scanColumnList,
740     DataValueDescriptor[] startKeyValue,
741     int startSearchOperator,
742     Qualifier qualifier[][],
743     DataValueDescriptor[] stopKeyValue,
744     int stopSearchOperator,
745     StaticCompiledOpenConglomInfo static_info,
746     DynamicCompiledOpenConglomInfo dynamic_info)
747             throws StandardException
748     {
749         // Create a new b-tree secondary index scan.
750
B2IForwardScan b2is = new B2IForwardScan();
751
752         // Initialize it.
753
b2is.init(xact_manager, rawtran,
754                   hold,
755                   open_mode,
756                   lock_level,
757                   locking_policy,
758                   isolation_level,
759                   true /* get locks on base table as part of open */,
760                   scanColumnList,
761                   startKeyValue, startSearchOperator,
762                   qualifier,
763                   stopKeyValue, stopSearchOperator, this, new B2IUndo(),
764                   (B2IStaticCompiledInfo) static_info,
765                   dynamic_info);
766
767         // Return it to the caller.
768
return b2is;
769     }
770
771     /**
772      * Open a b-tree compress scan.
773      * <p>
774      * B2I does not support a compress scan.
775      * <p>
776      * @see Conglomerate#defragmentConglomerate
777      *
778      * @exception StandardException Standard exception policy.
779      **/

780     public ScanManager defragmentConglomerate(
781     TransactionManager xact_manager,
782     Transaction rawtran,
783     boolean hold,
784     int open_mode,
785     int lock_level,
786     LockingPolicy locking_policy,
787     int isolation_level)
788             throws StandardException
789     {
790         throw StandardException.newException(
791             SQLState.BTREE_UNIMPLEMENTED_FEATURE);
792     }
793
794     public void purgeConglomerate(
795     TransactionManager xact_manager,
796     Transaction rawtran)
797         throws StandardException
798     {
799         // currently on work to do in btree's for purge rows, purging
800
// happens best when split is about to happen.
801
return;
802     }
803
804     public void compressConglomerate(
805     TransactionManager xact_manager,
806     Transaction rawtran)
807         throws StandardException
808     {
809         B2IController b2ic = new B2IController();
810
811         try
812         {
813             int open_mode = TransactionController.OPENMODE_FORUPDATE;
814
815             // Do the actual open of the container in the super class.
816
b2ic.init(
817                 xact_manager, // current transaction
818
xact_manager.getRawStoreXact(), // current raw store xact
819
false, // Not holdable
820
open_mode,
821                 TransactionController.MODE_TABLE,
822                 xact_manager.getRawStoreXact().newLockingPolicy(
823                     LockingPolicy.MODE_CONTAINER,
824                     TransactionController.ISOLATION_SERIALIZABLE, true),
825                 true,
826                 this,
827                 new B2IUndo(),
828                 (B2IStaticCompiledInfo) null,
829                 (DynamicCompiledOpenConglomInfo) null);
830
831             b2ic.getContainer().compressContainer();
832
833         }
834         finally
835         {
836             b2ic.close();
837         }
838
839         return;
840     }
841
842     /**
843      * Return an open StoreCostController for the conglomerate.
844      * <p>
845      * Return an open StoreCostController which can be used to ask about
846      * the estimated row counts and costs of ScanController and
847      * ConglomerateController operations, on the given conglomerate.
848      * <p>
849      * @param xact_manager The TransactionController under which this
850      * operation takes place.
851      * @param rawtran raw transaction context in which scan is managed.
852      *
853      * @return The open StoreCostController.
854      *
855      * @exception StandardException Standard exception policy.
856      *
857      * @see StoreCostController
858      **/

859     public StoreCostController openStoreCost(
860     TransactionManager xact_manager,
861     Transaction rawtran)
862         throws StandardException
863     {
864         B2ICostController b2icost = new B2ICostController();
865
866         b2icost.init(xact_manager, this, rawtran);
867
868         return(b2icost);
869     }
870
871     /**
872     Drop this b-tree secondary index.
873     @see Conglomerate#drop
874     @see BTree#drop
875
876     @exception StandardException Standard exception policy.
877     **/

878     public void drop(TransactionManager xact_manager)
879         throws StandardException
880     {
881         // HACK to get around problem where index is dropped after the base
882
// table.
883
ConglomerateController base_cc = null;
884
885
886         /* Get X table lock to make sure no thread is accessing index */
887         base_cc =
888             lockTable(
889                 xact_manager,
890                 TransactionController.OPENMODE_FORUPDATE,
891                 TransactionController.MODE_TABLE,
892                 TransactionController.ISOLATION_REPEATABLE_READ);
893
894         xact_manager.getRawStoreXact().dropContainer(id);
895
896         if (base_cc != null)
897             base_cc.close();
898     }
899
900     /**
901      * Return static information about the conglomerate to be included in a
902      * a compiled plan.
903      * <p>
904      * The static info would be valid until any ddl was executed on the
905      * conglomid, and would be up to the caller to throw away when that
906      * happened. This ties in with what language already does for other
907      * invalidation of static info. The type of info in this would be
908      * containerid and array of format id's from which templates can be created.
909      * The info in this object is read only and can be shared among as many
910      * threads as necessary.
911      * <p>
912      *
913      * @return The static compiled information.
914      *
915      * @param conglomId The identifier of the conglomerate to open.
916      *
917      * @exception StandardException Standard exception policy.
918      **/

919     public StaticCompiledOpenConglomInfo getStaticCompiledConglomInfo(
920     TransactionController xact_manager,
921     long conglomId)
922         throws StandardException
923     {
924         return(new B2IStaticCompiledInfo(xact_manager, this));
925     }
926
927     /*
928     ** Methods of Storable (via Conglomerate via BTree).
929     ** This class is responsible for re/storing its
930     ** own state and calling its superclass to store its'.
931     */

932
933
934     /*
935      * Storable interface, implies Externalizable, TypedFormat
936      */

937
938
939     /**
940         Return my format identifier.
941
942         @see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId
943     */

944     public int getTypeFormatId()
945     {
946         return StoredFormatIds.ACCESS_B2I_V3_ID;
947     }
948
949     /**
950     Store the stored representation of the column value in the stream.
951     It might be easier to simply store the properties - which would certainly
952     make upgrading easier.*/

953     public void writeExternal_v36(ObjectOutput JavaDoc out) throws IOException JavaDoc {
954         super.writeExternal(out);
955         out.writeLong(baseConglomerateId);
956         out.writeInt(rowLocationColumn);
957     }
958
959     /**
960     Restore the in-memory representation from the stream.
961
962     @exception ClassNotFoundException Thrown if the stored representation is
963     serialized and a class named in the stream could not be found.
964
965     @see java.io.Externalizable#readExternal
966     */

967     public void readExternal_v36(ObjectInput JavaDoc in)
968         throws IOException JavaDoc, ClassNotFoundException JavaDoc
969     {
970         super.readExternal(in);
971         
972         // XXX (nat) need to improve error handling
973
baseConglomerateId = in.readLong();
974         rowLocationColumn = in.readInt();
975         //set the default (Ascending) sort order
976
ascDescInfo = new boolean[nKeyFields];
977         for (int i=0 ; i < ascDescInfo.length; i++)
978             ascDescInfo[i] = true;
979     }
980
981
982     /**
983     Store the stored representation of the column value in the stream.
984     It might be easier to simply store the properties - which would certainly
985     make upgrading easier.
986
987     */

988     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc {
989         super.writeExternal(out);
990         out.writeLong(baseConglomerateId);
991         out.writeInt(rowLocationColumn);
992
993         // if the conglomerate type is not not the version2
994
// sorting information is stored from version V3(release 3.7)
995
if (conglom_format_id != StoredFormatIds.ACCESS_B2I_V2_ID)
996         {
997             //write the coulmsn sort information as bits
998
FormatableBitSet ascDescBits = new FormatableBitSet(ascDescInfo.length);
999             for (int i = 0; i < ascDescInfo.length; i++)
1000            {
1001                if (ascDescInfo[i])
1002                    ascDescBits.set(i);
1003            }
1004            ascDescBits.writeExternal(out);
1005        }
1006
1007    }
1008
1009    /**
1010    Restore the in-memory representation from the stream.
1011
1012    @exception ClassNotFoundException Thrown if the stored representation is
1013    serialized and a class named in the stream could not be found.
1014
1015    @see java.io.Externalizable#readExternal
1016    */

1017    private final void localReadExternal(ObjectInput JavaDoc in)
1018        throws IOException JavaDoc, ClassNotFoundException JavaDoc
1019    {
1020        super.readExternal(in);
1021        
1022        // XXX (nat) need to improve error handling
1023
baseConglomerateId = in.readLong();
1024        rowLocationColumn = in.readInt();
1025
1026        // if the conglomerate type is not the version2
1027
// sorting info is avaialable from version v3(release 3.7)
1028
if (conglom_format_id != StoredFormatIds.ACCESS_B2I_V2_ID)
1029        {
1030            // read the column sort order info
1031
FormatableBitSet ascDescBits = new FormatableBitSet();
1032            ascDescBits.readExternal(in);
1033            ascDescInfo = new boolean[ascDescBits.getLength()];
1034            for(int i =0 ; i < ascDescBits.getLength(); i++)
1035                ascDescInfo[i] = ascDescBits.isSet(i);
1036        }
1037        else
1038        {
1039            //set the default (Ascending) sort order
1040
ascDescInfo = new boolean[nKeyFields];
1041            for (int i=0 ; i < ascDescInfo.length; i++)
1042                ascDescInfo[i] = true;
1043
1044        }
1045
1046    }
1047
1048    public void readExternal(ObjectInput JavaDoc in)
1049        throws IOException JavaDoc, ClassNotFoundException JavaDoc
1050    {
1051        localReadExternal(in);
1052    }
1053    public void readExternalFromArray(ArrayInputStream in)
1054        throws IOException JavaDoc, ClassNotFoundException JavaDoc
1055    {
1056        localReadExternal(in);
1057    }
1058}
1059
Popular Tags