use of org.apache.derby.iapi.store.raw.ContainerHandle in project derby by apache.
the class Heap method openScan.
/**
* Open a heap scan controller.
* <p>
*
* @see Conglomerate#openScan
*
* @exception StandardException Standard exception policy.
*/
public ScanManager openScan(TransactionManager xact_manager, Transaction rawtran, boolean hold, int open_mode, int lock_level, LockingPolicy locking_policy, int isolation_level, FormatableBitSet scanColumnList, DataValueDescriptor[] startKeyValue, int startSearchOperator, Qualifier[][] qualifier, DataValueDescriptor[] stopKeyValue, int stopSearchOperator, StaticCompiledOpenConglomInfo static_info, DynamicCompiledOpenConglomInfo dynamic_info) throws StandardException {
if (SanityManager.DEBUG) {
if ((open_mode & TransactionController.OPENMODE_LOCK_ROW_NOWAIT) != 0) {
SanityManager.THROWASSERT("Bad open mode to Heap#openScan:" + Integer.toHexString(open_mode));
}
}
// only make sense for ordered storage structures).
if (!RowUtil.isRowEmpty(startKeyValue) || !RowUtil.isRowEmpty(stopKeyValue)) {
throw StandardException.newException(SQLState.HEAP_UNIMPLEMENTED_FEATURE);
}
OpenConglomerate open_conglom = new OpenHeap();
if (open_conglom.init((ContainerHandle) null, this, this.format_ids, this.collation_ids, xact_manager, rawtran, hold, open_mode, lock_level, locking_policy, dynamic_info) == null) {
throw StandardException.newException(SQLState.HEAP_CONTAINER_NOT_FOUND, id.getContainerId());
}
HeapScan heapscan = new HeapScan();
heapscan.init(open_conglom, scanColumnList, startKeyValue, startSearchOperator, qualifier, stopKeyValue, stopSearchOperator);
return (heapscan);
}
use of org.apache.derby.iapi.store.raw.ContainerHandle in project derby by apache.
the class HeapConglomerateFactory method readConglomerate.
/**
* Return Conglomerate object for conglomerate with container_key.
* <p>
* Return the Conglomerate Object. This is implementation specific.
* Examples of what will be done is using the key 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.
*
* @param xact_mgr transaction to perform the create in.
* @param container_key The unique id of the existing conglomerate.
*
* @return An instance of the conglomerate.
*
* @exception StandardException Standard exception policy.
*/
public Conglomerate readConglomerate(TransactionManager xact_mgr, ContainerKey container_key) throws StandardException {
ContainerHandle container = null;
Page page = null;
DataValueDescriptor[] control_row = new DataValueDescriptor[1];
try {
// open container to read the Heap object out of it's control row.
container = xact_mgr.getRawStoreXact().openContainer(container_key, (LockingPolicy) null, 0);
if (container == null) {
throw StandardException.newException(SQLState.STORE_CONGLOMERATE_DOES_NOT_EXIST, container_key.getContainerId());
}
// row in slot 0 of heap page 1 which is just a single column with
// the heap entry.
control_row[0] = new Heap();
page = container.getPage(ContainerHandle.FIRST_PAGE_NUMBER);
RecordHandle rh = page.fetchFromSlot((RecordHandle) null, 0, control_row, (FetchDescriptor) null, true);
if (SanityManager.DEBUG) {
SanityManager.ASSERT(rh != null);
// for now the control row is always the first id assigned on
// page 1.
SanityManager.ASSERT(rh.getId() == 6);
}
} finally {
if (page != null)
page.unlatch();
if (container != null)
container.close();
}
return ((Conglomerate) control_row[0]);
}
use of org.apache.derby.iapi.store.raw.ContainerHandle in project derby by apache.
the class HeapController method load.
protected long load(TransactionManager xact_manager, Heap heap, boolean createConglom, RowLocationRetRowSource rowSource) throws StandardException {
long num_rows_loaded = 0;
if (SanityManager.DEBUG) {
SanityManager.ASSERT(open_conglom == null, "load expects container handle to be closed on entry.");
}
// The individual rows that are inserted are not logged. To use a
// logged interface, use insert. RESOLVE: do we want to allow client
// to use the load interface even for logged insert?
int mode = (ContainerHandle.MODE_FORUPDATE | ContainerHandle.MODE_UNLOGGED);
// page allocation.
if (createConglom)
mode |= ContainerHandle.MODE_CREATE_UNLOGGED;
OpenConglomerate open_conglom = new OpenHeap();
if (open_conglom.init((ContainerHandle) null, heap, heap.format_ids, heap.collation_ids, xact_manager, xact_manager.getRawStoreXact(), false, mode, TransactionController.MODE_TABLE, xact_manager.getRawStoreXact().newLockingPolicy(LockingPolicy.MODE_CONTAINER, TransactionController.ISOLATION_SERIALIZABLE, true), (DynamicCompiledOpenConglomInfo) null) == null) {
throw StandardException.newException(SQLState.HEAP_CONTAINER_NOT_FOUND, heap.getId().getContainerId());
}
this.init(open_conglom);
// For bulk loading, we always use only brand new page because the row
// insertion itself is not logged. We cannot pollute pages with
// pre-existing data with unlogged rows because nobody is going to wipe
// out these rows if the transaction rolls back. We are counting on
// the allocation page rollback to obliterate these rows if the
// transaction fails, or, in the CREAT_UNLOGGED case, the whole
// container to be removed.
Page page = open_conglom.getContainer().addPage();
boolean callbackWithRowLocation = rowSource.needsRowLocation();
RecordHandle rh;
HeapRowLocation rowlocation;
if (callbackWithRowLocation || rowSource.needsRowLocationForDeferredCheckConstraints())
rowlocation = new HeapRowLocation();
else
rowlocation = null;
FormatableBitSet validColumns = rowSource.getValidColumns();
try {
// get the next row and its valid columns from the rowSource
DataValueDescriptor[] row;
while ((row = rowSource.getNextRowFromRowSource()) != null) {
num_rows_loaded++;
if (SanityManager.DEBUG) {
// Make sure valid columns are in the list. The RowUtil
// call is too expensive to make in a released system for
// every insert.
int invalidColumn = RowUtil.columnOutOfRange(row, validColumns, heap.format_ids.length);
if (invalidColumn >= 0) {
throw (StandardException.newException(SQLState.HEAP_TEMPLATE_MISMATCH, invalidColumn, heap.format_ids.length));
}
}
// Insert it onto this page as long as it can fit more rows.
if ((rh = page.insert(row, validColumns, Page.INSERT_DEFAULT, AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD)) == null) {
// Insert faied, row did not fit. Get a new page.
page.unlatch();
page = null;
page = open_conglom.getContainer().addPage();
// RESOLVE (mikem) - no long rows yet so the following code
// will get an exception from the raw store for a row that
// does not fit on a page.
//
// Multi-thread considerations aside, the raw store will
// guarantee that any size row will fit on an empty page.
rh = page.insert(row, validColumns, Page.INSERT_OVERFLOW, AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD);
}
// and go for the next row.
if (callbackWithRowLocation) {
rowlocation.setFrom(rh);
rowSource.rowLocation(rowlocation);
}
if (rowSource.needsRowLocationForDeferredCheckConstraints()) {
rowlocation.setFrom(rh);
rowSource.offendingRowLocation(rowlocation, heap.getContainerid());
}
}
page.unlatch();
page = null;
// it is unlogged.
if (!heap.isTemporary())
open_conglom.getContainer().flushContainer();
} finally {
// If an error happened here, don't bother flushing the
// container since the changes should be rolled back anyhow.
close();
}
return (num_rows_loaded);
}
use of org.apache.derby.iapi.store.raw.ContainerHandle in project derby by apache.
the class B2IForwardScan method reopen.
/**
* Open the container after it has been closed previously.
* <p>
* Open the container, obtaining necessary locks. Most work is actually
* done by RawStore.openContainer(). Will only reopen() if the container
* is not already open.
*
* @exception StandardException Standard exception policy.
*/
public ContainerHandle reopen() throws StandardException {
ContainerHandle container = super.reopen();
B2I b2i = (B2I) getConglomerate();
// open and lock the base table.
int base_open_mode = getOpenMode() | TransactionController.OPENMODE_FOR_LOCK_ONLY;
// TODO - figure out what to do with static_info stuff
// open the base conglomerate - just to get lock
/*
if (static_info != null)
{
base_cc_for_locking =
xact_manager.openCompiledConglomerate(
false,
base_open_mode, lock_level, isolation_level,
static_info.base_table_static_info,
((Conglomerate) static_info.getConglom()).
getDynamicCompiledConglomInfo(
b2i.baseConglomerateId));
}
else
*/
{
base_cc_for_locking = getXactMgr().openConglomerate(b2i.baseConglomerateId, false, base_open_mode, init_lock_level, init_isolation_level);
setLockingPolicy(b2i.getBtreeLockingPolicy(getXactMgr().getRawStoreXact(), getLockLevel(), getOpenMode(), init_isolation_level, base_cc_for_locking, this));
}
return (container);
}
use of org.apache.derby.iapi.store.raw.ContainerHandle 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