use of org.apache.derby.impl.store.access.btree.ControlRow in project derby by apache.
the class B2IFactory method readConglomerate.
/**
* Return Conglomerate object for conglomerate with conglomid.
* <p>
* Return the Conglomerate Object. This is implementation specific.
* Examples of what will be done is using the id to find the file where
* the conglomerate is located, and then executing implementation specific
* code to instantiate an object from reading a "special" row from a
* known location in the file. In the btree case the btree conglomerate
* is stored as a column in the control row on the root page.
* <p>
* This operation is costly so it is likely an implementation using this
* will cache the conglomerate row in memory so that subsequent accesses
* need not perform this operation.
* <p>
* The btree object returned by this routine may be installed in a cache
* so the object must not change.
*
* @return An instance of the conglomerate.
*
* @exception StandardException Standard exception policy.
*/
public Conglomerate readConglomerate(TransactionManager xact_manager, ContainerKey container_key) throws StandardException {
Conglomerate btree = null;
ContainerHandle container = null;
ControlRow root = null;
try {
// open readonly, with no locks. Dirty read is ok as it is the
// responsibility of client code to make sure this data is not
// changing while being read. The only changes that currently
// happen to this data is creation and deletion - no updates
// ever happen to btree conglomerates.
container = (xact_manager.getRawStoreXact()).openContainer(container_key, (LockingPolicy) null, ContainerHandle.MODE_READONLY);
if (container == null) {
throw StandardException.newException(SQLState.STORE_CONGLOMERATE_DOES_NOT_EXIST, container_key.getContainerId());
}
// The conglomerate is located in the control row on the root page.
root = ControlRow.get(container, BTree.ROOTPAGEID);
if (SanityManager.DEBUG)
SanityManager.ASSERT(root.getPage().isLatched());
// read the Conglomerate from it's entry in the control row.
btree = (Conglomerate) root.getConglom(B2I.FORMAT_NUMBER);
if (SanityManager.DEBUG)
SanityManager.ASSERT(btree instanceof B2I);
} finally {
if (root != null)
root.release();
if (container != null)
container.close();
}
return (btree);
}
use of org.apache.derby.impl.store.access.btree.ControlRow 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