use of org.apache.derby.iapi.store.raw.RecordHandle in project derby by apache.
the class BasePage method insertNoOverflow.
protected RecordHandle insertNoOverflow(int slot, Object[] row, FormatableBitSet validColumns, LogicalUndo undo, byte insertFlag, int overflowThreshold) throws StandardException {
if (SanityManager.DEBUG) {
SanityManager.ASSERT(isLatched());
}
if (!owner.updateOK()) {
throw StandardException.newException(SQLState.DATA_CONTAINER_READ_ONLY);
}
if (slot < FIRST_SLOT_NUMBER || slot > recordCount) {
throw StandardException.newException(SQLState.DATA_SLOT_NOT_ON_PAGE);
}
if (!allowInsert())
return null;
RawTransaction t = owner.getTransaction();
// logical operations not allowed in internal transactions.
if (undo != null) {
t.checkLogicalOperationOk();
}
int recordId;
RecordHandle handle;
do {
// loop until we get a new record id we can get a lock on.
// If we can't get the lock without waiting then assume the record
// id is owned by another xact. The current heap overflow
// algorithm makes this likely, as it first try's to insert a row
// telling raw store to fail if it doesn't fit on the page getting
// a lock on an id that never makes it to disk. The inserting
// transaction will hold a lock on this "unused" record id until
// it commits. The page can leave the cache at this point, and
// the inserting transaction has not dirtied the page (it failed
// after getting the lock but before logging anything), another
// inserting transaction will then get the same id as the
// previous inserter - thus the loop on lock waits.
//
// The lock we request indicates that this is a lock for insert,
// which the locking policy may use to perform locking concurrency
// optimizations.
recordId = newRecordIdAndBump();
handle = new RecordId(getPageId(), recordId, slot);
} while (!owner.getLockingPolicy().lockRecordForWrite(t, handle, true, /* lock is for insert */
false));
owner.getActionSet().actionInsert(t, this, slot, recordId, row, validColumns, undo, insertFlag, 0, false, -1, (DynamicByteArrayOutputStream) null, -1, overflowThreshold);
return handle;
}
use of org.apache.derby.iapi.store.raw.RecordHandle in project derby by apache.
the class BasePage method copyInto.
/**
* Copy num_rows from srcPage, src_slot into this page starting at dest_slot.
* This is destination page of the the copy half of copy and Purge.
*
* @see Page#copyAndPurge
*/
private void copyInto(BasePage srcPage, int src_slot, int num_rows, int dest_slot) throws StandardException {
if ((dest_slot < 0) || dest_slot > recordCount) {
throw StandardException.newException(SQLState.DATA_SLOT_NOT_ON_PAGE);
}
RawTransaction t = owner.getTransaction();
// get num_rows row locks, need to predict what those recordIds will be
int[] recordIds = new int[num_rows];
// RESOLVE - MT problem ?
PageKey pageId = getPageId();
for (int i = 0; i < num_rows; i++) {
if (i == 0)
recordIds[i] = newRecordId();
else
recordIds[i] = newRecordId(recordIds[i - 1]);
RecordHandle handle = new RecordId(pageId, recordIds[i], i);
owner.getLockingPolicy().lockRecordForWrite(t, handle, false, true);
}
// RESOLVE: need try block here to invalidate self and crash the system
owner.getActionSet().actionCopyRows(t, this, srcPage, dest_slot, num_rows, src_slot, recordIds);
}
use of org.apache.derby.iapi.store.raw.RecordHandle in project derby by apache.
the class BasePage method purgeAtSlot.
/**
* Purge one or more rows on a non-overflow page.
*
* @see Page#purgeAtSlot
* @exception StandardException Standard exception policy.
*/
public void purgeAtSlot(int slot, int numpurges, boolean needDataLogged) throws StandardException {
if (SanityManager.DEBUG) {
SanityManager.ASSERT(isLatched());
if (isOverflowPage())
SanityManager.THROWASSERT("purge committed deletes on an overflow page. Page = " + this);
}
if (numpurges <= 0)
return;
if (!owner.updateOK()) {
throw StandardException.newException(SQLState.DATA_CONTAINER_READ_ONLY);
}
if ((slot < 0) || ((slot + numpurges) > recordCount)) {
throw StandardException.newException(SQLState.DATA_SLOT_NOT_ON_PAGE);
}
RawTransaction t = owner.getTransaction();
// lock the records to be purged
int[] recordIds = new int[numpurges];
// RESOLVE: MT problem ?
PageKey pageId = getPageId();
for (int i = 0; i < numpurges; i++) {
recordIds[i] = getHeaderAtSlot(slot + i).getId();
// get row lock on head row piece
RecordHandle handle = getRecordHandleAtSlot(slot);
owner.getLockingPolicy().lockRecordForWrite(t, handle, false, true);
if (owner.isTemporaryContainer() || entireRecordOnPage(slot + i))
continue;
// row[slot+i] has overflow rows and/or long columns, reclaim
// them in a loop.
RecordHandle headRowHandle = getHeaderAtSlot(slot + i).getHandle(pageId, slot + i);
purgeRowPieces(t, slot + i, headRowHandle, needDataLogged);
}
owner.getActionSet().actionPurge(t, this, slot, numpurges, recordIds, needDataLogged);
}
use of org.apache.derby.iapi.store.raw.RecordHandle in project derby by apache.
the class BaseContainer method removePage.
/**
* Remove a page from this container. The page will be unlatched by this
* routine before it returns.
*
* Unlike addPage, this method done as part of the user transaction.
* The removed page is not usable by anyone until the user transaction
* comits.
* If the user transaction rolls back, the removed page is un-removed.
*
* <BR> MT - thread aware -
*
* @param handle the container handle that has opened the container and latched the page
* @param page the latched page that is to be deallocated
*
* @exception StandardException Standard Derby error policy
*/
protected void removePage(BaseContainerHandle handle, BasePage page) throws StandardException {
try {
if (SanityManager.DEBUG) {
SanityManager.ASSERT(page.isLatched(), "page is not latched");
}
// get dealloc lock nowait on the page to be deallocated
// this lock is held until this transaction commits.
// then gc can free this page
RecordHandle deallocLock = page.makeRecordHandle(RecordHandle.DEALLOCATE_PROTECTION_HANDLE);
// don't get deallocLock wait because caller have a page latched
if (!getDeallocLock(handle, deallocLock, false, /* no wait */
false)) {
throw StandardException.newException(SQLState.DATA_CANNOT_GET_DEALLOC_LOCK, page.getIdentity());
}
deallocatePage(handle, page);
} finally {
if (page != null)
page.unlatch();
}
}
use of org.apache.derby.iapi.store.raw.RecordHandle in project derby by apache.
the class LockCount method reached.
/*
** Lock escalation related
*/
/*
** Methods of Limit
*/
public void reached(CompatibilitySpace compatibilitySpace, Object group, int limit, Enumeration lockList, int lockCount) throws StandardException {
// Count row locks by table
Dictionary<ContainerKey, LockCount> containers = new java.util.Hashtable<ContainerKey, LockCount>();
for (; lockList.hasMoreElements(); ) {
Object plainLock = lockList.nextElement();
if (!(plainLock instanceof RecordHandle)) {
// only interested in rows locks
continue;
}
ContainerKey ckey = ((RecordHandle) plainLock).getContainerId();
LockCount lc = (LockCount) containers.get(ckey);
if (lc == null) {
lc = new LockCount();
containers.put(ckey, lc);
}
lc.count++;
}
// Determine the threshold for lock escalation
// based upon our own limit, not the current count
int threshold = limit / (containers.size() + 1);
if (threshold < (limit / 4))
threshold = limit / 4;
// try to table lock all tables that are above
// this threshold
boolean didEscalate = false;
for (Enumeration<ContainerKey> e = containers.keys(); e.hasMoreElements(); ) {
ContainerKey ckey = e.nextElement();
LockCount lc = containers.get(ckey);
if (lc.count < threshold) {
continue;
}
try {
if (openContainer(ckey, new RowLocking3Escalate(getLockFactory()), ContainerHandle.MODE_OPEN_FOR_LOCK_ONLY | ContainerHandle.MODE_FORUPDATE | ContainerHandle.MODE_LOCK_NOWAIT) != null) {
didEscalate = true;
}
} catch (StandardException se) {
if (!se.isLockTimeout()) {
// just fall through.
throw se;
}
}
}
// of BaseContainerHandle look for its ContainerKey within it.
if (didEscalate) {
notifyObservers(LOCK_ESCALATE);
checkObserverException();
}
}
Aggregations