use of org.apache.derby.iapi.store.raw.LockingPolicy 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.iapi.store.raw.LockingPolicy in project derby by apache.
the class BaseDataFileFactory method dropContainer.
/**
* Drop a container.
*
* <P><B>Synchronisation</B>
* <P>
* This call will mark the container as dropped and then obtain an CX lock
* (table level exclusive lock) on the container. Once a container has
* been marked as dropped it cannot be retrieved by an openContainer()
* call unless explicitly with droppedOK.
* <P>
* Once the exclusive lock has been obtained the container is removed
* and all its pages deallocated. The container will be fully removed
* at the commit time of the transaction.
*
* @exception StandardException Standard Derby error policy
*/
public void dropContainer(RawTransaction t, ContainerKey ckey) throws StandardException {
boolean tmpContainer = (ckey.getSegmentId() == ContainerHandle.TEMPORARY_SEGMENT);
LockingPolicy cl = null;
if (!tmpContainer) {
if (isReadOnly()) {
throw StandardException.newException(SQLState.DATA_CONTAINER_READ_ONLY);
}
cl = t.newLockingPolicy(LockingPolicy.MODE_CONTAINER, TransactionController.ISOLATION_SERIALIZABLE, true);
if (SanityManager.DEBUG)
SanityManager.ASSERT(cl != null);
}
// close all open containers and 'onCommit' objects of this container
t.notifyObservers(ckey);
RawContainerHandle containerHdl = (RawContainerHandle) t.openContainer(ckey, cl, ContainerHandle.MODE_FORUPDATE);
// happening thru some means other than the lock we are getting here.
try {
if (containerHdl == null || containerHdl.getContainerStatus() != RawContainerHandle.NORMAL) {
// If we are a temp container, don't worry about it.
if (tmpContainer) {
if (containerHdl != null)
containerHdl.removeContainer((LogInstant) null);
return;
} else {
throw StandardException.newException(SQLState.DATA_CONTAINER_VANISHED, ckey);
}
}
// Container exist, is updatable and we got the lock.
if (tmpContainer) {
containerHdl.dropContainer((LogInstant) null, true);
containerHdl.removeContainer((LogInstant) null);
} else {
ContainerOperation lop = new ContainerOperation(containerHdl, ContainerOperation.DROP);
// mark the container as pre-dirtied so that if a checkpoint
// happens after the log record is sent to the log stream, the
// cache cleaning will wait for this change.
containerHdl.preDirty(true);
try {
t.logAndDo(lop);
} finally {
// in case logAndDo fail, make sure the container is not
// stuck in preDirty state.
containerHdl.preDirty(false);
}
// remember this as a post commit work item
Serviceable p = new ReclaimSpace(ReclaimSpace.CONTAINER, ckey, this, true);
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) {
SanityManager.DEBUG(DaemonService.DaemonTrace, "Add post commit work " + p);
}
}
t.addPostCommitWork(p);
}
} finally {
if (containerHdl != null)
containerHdl.close();
}
}
use of org.apache.derby.iapi.store.raw.LockingPolicy 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.LockingPolicy in project derby by apache.
the class BaseContainer method compressContainer.
/*
** Implementation specific methods
*/
/**
* Release free space to the OS.
* <P>
* As is possible release any free space to the operating system. This
* will usually mean releasing any free pages located at the end of the
* file using the java truncate() interface.
*
* @exception StandardException Standard Derby error policy
*/
public void compressContainer(BaseContainerHandle handle) throws StandardException {
RawTransaction ntt = handle.getTransaction().startNestedTopTransaction();
int mode = handle.getMode();
if (SanityManager.DEBUG) {
SanityManager.ASSERT((mode & ContainerHandle.MODE_FORUPDATE) == ContainerHandle.MODE_FORUPDATE, "addPage handle not for update");
}
// crashed.
if ((mode & ContainerHandle.MODE_CREATE_UNLOGGED) == 0 && (mode & ContainerHandle.MODE_UNLOGGED) == ContainerHandle.MODE_UNLOGGED)
mode &= ~ContainerHandle.MODE_UNLOGGED;
// make a handle which is tied to the ntt, not to the user transaction
// this handle is tied to. The container is already locked by the
// user transaction, open it nolock
BaseContainerHandle allocHandle = (BaseContainerHandle) ntt.openContainer(identity, (LockingPolicy) null, mode);
if (allocHandle == null) {
throw StandardException.newException(SQLState.DATA_ALLOC_NTT_CANT_OPEN, getSegmentId(), getContainerId());
}
CompatibilitySpace cs = ntt.getCompatibilitySpace();
// Latch this container, the commit will release the latch
ntt.getLockFactory().lockObject(cs, ntt, this, null, C_LockFactory.WAIT_FOREVER);
try {
incrementReusableRecordIdSequenceNumber();
compressContainer(ntt, allocHandle);
} finally {
ntt.commit();
ntt.close();
}
}
use of org.apache.derby.iapi.store.raw.LockingPolicy in project derby by apache.
the class BaseContainer method getDeallocLock.
/**
* Get the special dealloc lock on the page - the lock is gotten by the
* transaction that owns the container handle
*
* @exception StandardException Standard Derby error policy
*/
protected boolean getDeallocLock(BaseContainerHandle handle, RecordHandle deallocLock, boolean wait, boolean zeroDuration) throws StandardException {
// get deallocate lock on page so that the GC won't attempt to
// free and re-allocate it until the transaction commits
RawTransaction tran = handle.getTransaction();
LockingPolicy lp = tran.newLockingPolicy(LockingPolicy.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ, // striterOK
true);
PageKey pkey = new PageKey(identity, deallocLock.getPageNumber());
if (lp != null) {
if (zeroDuration)
return lp.zeroDurationLockRecordForWrite(tran, deallocLock, false, wait);
else
return lp.lockRecordForWrite(tran, deallocLock, false, wait);
} else {
throw StandardException.newException(SQLState.DATA_CANNOT_GET_DEALLOC_LOCK, pkey);
}
}
Aggregations