use of org.apache.derby.impl.store.access.btree.OpenBTree in project derby by apache.
the class B2I method create.
/*
** Methods of B2I.
*/
/**
* Create an empty secondary index b-tree, using the generic b-tree to do the
* generic part of the creation process.
*
* 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.
*
* 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);
// 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
// default values - ascending order
ascDescInfo[i] = true;
}
// 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(// current user xact
(TransactionManager) xact_manager, // current xact
(TransactionManager) xact_manager, // have init open the container.
(ContainerHandle) null, rawtran, false, (ContainerHandle.MODE_FORUPDATE), TransactionController.MODE_TABLE, // get table level lock.
b2i_locking_policy, this, // no logical undo necessary, as
(LogicalUndo) null, // 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();
}
use of org.apache.derby.impl.store.access.btree.OpenBTree in project derby by apache.
the class B2IUndo method findUndo.
/**
* Find the page and record to undo. If no logical undo is necessary,
* i.e., row has not moved, then just return the latched page where undo
* should go. If the record has moved, it has a new recordId on the new
* page, this routine needs to call pageOp.resetRecord with the new
* RecordHandle so that the logging system can update the compensation
* Operation with the new location.
*
* @param rawtran the transaction doing the rollback
* @param pageOp the page operation that supports logical undo. This
* LogicalUndo function pointer is a field of that
* pageOperation
* @param in data stored in the log stream that contains the record
* data necessary to restore the row.
*
* @exception StandardException Standard Derby error policy
* @exception IOException Method may read from InputStream
*/
public Page findUndo(Transaction rawtran, LogicalUndoable pageOp, LimitObjectInput in) throws StandardException, IOException {
ControlRow root = null;
ControlRow control_row = null;
DataValueDescriptor[] logged_index_row_template = null;
DataValueDescriptor[] template = null;
Page ret_page = null;
ContainerHandle container = pageOp.getContainer();
RecordHandle rechandle = pageOp.getRecordHandle();
boolean ok_exit = false;
int compare_result = 1;
B2I btree = null;
try {
// Need Conglomerate to create templates - get from the root page.
root = ControlRow.get(container, BTree.ROOTPAGEID);
if (SanityManager.DEBUG)
SanityManager.ASSERT(root.getPage().isLatched());
btree = (B2I) root.getConglom(B2I.FORMAT_NUMBER);
if (SanityManager.DEBUG)
SanityManager.ASSERT(btree instanceof B2I);
// create a template for the logged index row from the conglomerate.
logged_index_row_template = btree.createTemplate(rawtran);
// create a template for the page index row from the conglomerate.
template = btree.createTemplate(rawtran);
} finally {
if (root != null)
root.release();
}
// Get logged row from record.
pageOp.restoreLoggedRow(logged_index_row_template, in);
// RESOLVE (mikem) - currently restoreLoggedRow() may latch and unlatch
// a page in the container (see ST059).
// Now get the page where the record used to be.
ok_exit = false;
try {
// "open" the btree, using recovery's already opened container
OpenBTree open_btree = new OpenBTree();
open_btree.init(// current user xact - not needed
(TransactionManager) null, // current xact - not needed
(TransactionManager) null, // recovery already opened container
pageOp.getContainer(), rawtran, false, ContainerHandle.MODE_FORUPDATE, // already opened.
TransactionManager.MODE_NONE, // don't get locks during undo
(BTreeLockingPolicy) null, btree, // no logical undo necessary, as
(LogicalUndo) null, // this code only does read.
(DynamicCompiledOpenConglomInfo) null);
// System.out.println(
// "calling logical undo, recordhandle = " + rechandle);
// System.out.println("calling logical undo, record= " +
// logged_index_row_template);
// Get the page where the record was originally, before splits
// could have possibly moved it.
control_row = ControlRow.get(open_btree, rechandle.getPageNumber());
// init compare_result, if record doesn't exist do the search
compare_result = 1;
if (control_row.getPage().recordExists(rechandle, true)) {
if (SanityManager.DEBUG) {
SanityManager.ASSERT(control_row.getPage().fetchNumFields(rechandle) == logged_index_row_template.length);
}
// create template for the page index row from the conglomerate.
RecordHandle ret_rechandle = control_row.getPage().fetchFromSlot((RecordHandle) null, control_row.getPage().getSlotNumber(rechandle), template, (FetchDescriptor) null, true);
// compare the 2 rows, and if they are the same then the raw
// store has the right page and record and there is no work to
// be done (this is usual case).
compare_result = ControlRow.compareIndexRowToKey(template, logged_index_row_template, logged_index_row_template.length, 1, open_btree.getColumnSortOrderInfo());
}
if (compare_result == 0) {
ret_page = control_row.getPage();
} else {
// if the 2 don't compare equal, search the btree from the root
// for the logged row, find the leaf, reset the row for the raw
// store, and return the new page latched.
// Create the objects needed for the insert.
SearchParameters sp = new SearchParameters(logged_index_row_template, ScanController.GE, template, open_btree, false);
control_row.release();
control_row = null;
control_row = ControlRow.get(open_btree, BTree.ROOTPAGEID).search(sp);
if (!sp.resultExact) {
if (SanityManager.DEBUG) {
SanityManager.THROWASSERT("B2IUndo - could not find key being searched for:" + ";key = " + RowUtil.toString(logged_index_row_template) + ";sp = " + sp + "control_row = " + control_row + "control_row.debugPage() = " + control_row.debugPage(open_btree) + "control_row.getPage() = " + control_row.getPage());
}
throw StandardException.newException(SQLState.BTREE_ROW_NOT_FOUND_DURING_UNDO);
} else {
RecordHandle rh = control_row.getPage().fetchFromSlot((RecordHandle) null, sp.resultSlot, new DataValueDescriptor[0], (FetchDescriptor) null, true);
pageOp.resetRecordHandle(rh);
ret_page = control_row.getPage();
}
}
ok_exit = true;
} finally {
// pageOp.getRecordHandle());
if ((!ok_exit) && (control_row != null))
control_row.release();
}
return (ret_page);
}
Aggregations