/** Initialize the scan, returning false if there was some error. */ public boolean init(TransactionManager tran) throws StandardException { if (SanityManager.DEBUG) { // We really expect to have at least one // merge run. SanityManager.ASSERT(mergeRuns != null); SanityManager.ASSERT(mergeRuns.size() > 0); // This sort scan also expects that the // caller has ensured that the sort buffer // capacity will hold a row from all the // merge runs. SanityManager.ASSERT(sortBuffer.capacity() >= mergeRuns.size()); } // Clear the sort buffer. sortBuffer.reset(); // Create an array to hold a scan controller // for each merge run. openScans = new StreamContainerHandle[mergeRuns.size()]; if (openScans == null) return false; // Open a scan on each merge run. int scanindex = 0; Enumeration e = mergeRuns.elements(); while (e.hasMoreElements()) { // get the container id long id = ((Long) e.nextElement()).longValue(); Transaction rawTran = tran.getRawStoreXact(); // get raw transaction int segmentId = StreamContainerHandle.TEMPORARY_SEGMENT; openScans[scanindex++] = rawTran.openStreamContainer(segmentId, id, hold); } // Load the initial rows. for (scanindex = 0; scanindex < openScans.length; scanindex++) mergeARow(scanindex); // Success! return true; }
/** * Create an empty secondary index b-tree, using the generic b-tree to do the generic part of the * creation process. * * <p>This routine opens the newly created container, adds a single page, and makes this page the * root by inserting a LeafControlRow onto this page at slot 0 and marking in that control row * that the page is a root page. * * <p>The following properties are specific to the b-tree secondary index: * * <UL> * <LI>"baseConglomerateId" (integer). The conglomerate id of the base conglomerate is never * actually accessed by the b-tree secondary index implementation, it only serves as a * namespace for row locks. This property is required. * <LI>"rowLocationColumn" (integer). The zero-based index into the row which the b-tree * secondary index will assume holds a @see RowLocation of the base row in the base * conglomerate. This value will be used for acquiring locks. In this implementation * RowLocationColumn must be the last key column. This property is required. * </UL> * * A secondary index i (a, b) on table t (a, b, c) would have rows which looked like (a, b, * row_location). baseConglomerateId is set to the conglomerate id of t. rowLocationColumns is set * to 2. allowsDuplicates would be set to false, @see BTree#create. To create a unique secondary * index set uniquenessColumns to 2, this means that the btree code will compare the key values * but not the row id when determing uniqueness. To create a nonunique secondary index set * uniquenessColumns to 3, this would mean that the uniqueness test would include the row location * and since all row locations will be unique all rows inserted into the index will be * differentiated (at least) by row location. * * @see BTree#create * @exception StandardException Standard exception policy. */ public void create( TransactionManager xact_manager, int segmentId, long input_conglomid, DataValueDescriptor[] template, ColumnOrdering[] columnOrder, int[] collationIds, Properties properties, int temporaryFlag) throws StandardException { String property_value = null; Transaction rawtran = xact_manager.getRawStoreXact(); if (properties == null) { throw (StandardException.newException( SQLState.BTREE_PROPERTY_NOT_FOUND, PROPERTY_BASECONGLOMID)); } // Get baseConglomerateId // property_value = properties.getProperty(PROPERTY_BASECONGLOMID); if (property_value == null) { throw (StandardException.newException( SQLState.BTREE_PROPERTY_NOT_FOUND, PROPERTY_BASECONGLOMID)); } if (SanityManager.DEBUG) { if (property_value == null) SanityManager.THROWASSERT(PROPERTY_BASECONGLOMID + "property not passed to B2I.create()"); } baseConglomerateId = Long.parseLong(property_value); // Get rowLocationColumn // property_value = properties.getProperty(PROPERTY_ROWLOCCOLUMN); if (SanityManager.DEBUG) { if (property_value == null) SanityManager.THROWASSERT(PROPERTY_ROWLOCCOLUMN + "property not passed to B2I.create()"); } if (property_value == null) { throw (StandardException.newException( SQLState.BTREE_PROPERTY_NOT_FOUND, PROPERTY_BASECONGLOMID)); } rowLocationColumn = Integer.parseInt(property_value); // Currently the row location column must be the last column (makes) // comparing the columns in the index easier. if (SanityManager.DEBUG) { SanityManager.ASSERT( rowLocationColumn == template.length - 1, "rowLocationColumn is not the last column in the index"); SanityManager.ASSERT(template[rowLocationColumn] instanceof RowLocation); // There must be at least one key column if (rowLocationColumn < 1) SanityManager.THROWASSERT( "rowLocationColumn (" + rowLocationColumn + ") expected to be >= 1"); } /* convert the sorting order information into a boolean array map. * If the sorting order for the columns is not provided, we * assign the default as Ascending Order. * array length is equal to template length, because column order * length changes whether it is unique or is non unique. store assumes * template length arrays. So, we make template length array and make * the last column as ascending instead of having lot of execeptions * code. */ ascDescInfo = new boolean[template.length]; for (int i = 0; i < ascDescInfo.length; i++) { if (columnOrder != null && i < columnOrder.length) ascDescInfo[i] = columnOrder[i].getIsAscending(); else ascDescInfo[i] = true; // default values - ascending order } // get collation ids from input collation ids, store it in the // conglom state. collation_ids = ConglomerateUtil.createCollationIds(template.length, collationIds); hasCollatedTypes = hasCollatedColumns(collation_ids); // Do the generic part of creating the b-tree. super.create( rawtran, segmentId, input_conglomid, template, properties, getTypeFormatId(), temporaryFlag); // open the base conglomerate - to get the lock ConglomerateController base_cc = xact_manager.openConglomerate( baseConglomerateId, false, TransactionController.OPENMODE_FOR_LOCK_ONLY, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE); OpenBTree open_btree = new OpenBTree(); BTreeLockingPolicy b2i_locking_policy = new B2ITableLocking3( rawtran, TransactionController.MODE_TABLE, rawtran.newLockingPolicy( LockingPolicy.MODE_CONTAINER, TransactionController.ISOLATION_SERIALIZABLE, true), base_cc, open_btree); // The following call will "open" the new btree. Create is // an interesting case. What we really want is read only table lock // on the base conglomerate and update locks on the index. For now // just get the update lock on the base table, this is done by the // lockTable() call made by base class. open_btree.init( (TransactionManager) xact_manager, // current user xact (TransactionManager) xact_manager, // current xact (ContainerHandle) null, // have init open the container. rawtran, false, (ContainerHandle.MODE_FORUPDATE), TransactionController.MODE_TABLE, b2i_locking_policy, // get table level lock. this, (LogicalUndo) null, // no logical undo necessary, as // initEmptyBtree() // work will be done single user and // rows will not move. (DynamicCompiledOpenConglomInfo) null); // Open the newly created container, and insert the first control row. LeafControlRow.initEmptyBtree(open_btree); open_btree.close(); base_cc.close(); }
/** * Create a new btree locking policy from scratch. * * @exception StandardException Standard exception policy. */ protected BTreeLockingPolicy getBtreeLockingPolicy( Transaction rawtran, int lock_level, int mode, int isolation_level, ConglomerateController base_cc, OpenBTree open_btree) throws StandardException { BTreeLockingPolicy ret_locking_policy = null; if (SanityManager.DEBUG) { SanityManager.ASSERT( (isolation_level == TransactionController.ISOLATION_SERIALIZABLE) || (isolation_level == TransactionController.ISOLATION_REPEATABLE_READ) || (isolation_level == TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK) || (isolation_level == TransactionController.ISOLATION_READ_COMMITTED) || (isolation_level == TransactionController.ISOLATION_READ_UNCOMMITTED), "bad isolation_level = " + isolation_level); } if (lock_level == TransactionController.MODE_TABLE) { ret_locking_policy = new B2ITableLocking3( rawtran, lock_level, rawtran.newLockingPolicy(LockingPolicy.MODE_CONTAINER, isolation_level, true), base_cc, open_btree); } else if (lock_level == TransactionController.MODE_RECORD) { if (isolation_level == TransactionController.ISOLATION_SERIALIZABLE) { ret_locking_policy = new B2IRowLocking3( rawtran, lock_level, rawtran.newLockingPolicy(LockingPolicy.MODE_RECORD, isolation_level, true), base_cc, open_btree); } else if ((isolation_level == TransactionController.ISOLATION_REPEATABLE_READ)) { ret_locking_policy = new B2IRowLockingRR( rawtran, lock_level, rawtran.newLockingPolicy(LockingPolicy.MODE_RECORD, isolation_level, true), base_cc, open_btree); } else if ((isolation_level == TransactionController.ISOLATION_READ_COMMITTED) || (isolation_level == TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK)) { ret_locking_policy = new B2IRowLocking2( rawtran, lock_level, rawtran.newLockingPolicy(LockingPolicy.MODE_RECORD, isolation_level, true), base_cc, open_btree); } else if (isolation_level == TransactionController.ISOLATION_READ_UNCOMMITTED) { ret_locking_policy = new B2IRowLocking1( rawtran, lock_level, rawtran.newLockingPolicy(LockingPolicy.MODE_RECORD, isolation_level, true), base_cc, open_btree); } } if (SanityManager.DEBUG) { SanityManager.ASSERT(ret_locking_policy != null, "ret_locking_policy == null"); } return (ret_locking_policy); }