use of org.apache.hyracks.storage.common.buffercache.ICachedPage in project asterixdb by apache.
the class RTree method updateParentForInsert.
private void updateParentForInsert(RTreeOpContext ctx) throws HyracksDataException {
boolean succeeded = false;
boolean writeLatched = false;
int parentId = ctx.getPathList().getLastPageId();
ICachedPage parentNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, parentId), false);
parentNode.acquireWriteLatch();
writeLatched = true;
ctx.getInteriorFrame().setPage(parentNode);
boolean foundParent = true;
try {
if (ctx.getInteriorFrame().getPageLsn() != ctx.getPathList().getLastPageLsn()) {
foundParent = false;
while (true) {
if (ctx.getInteriorFrame().findTupleByPointer(ctx.getSplitKey().getLeftTuple(), ctx.getCmp()) != -1) {
// found the parent
foundParent = true;
break;
}
int rightPage = ctx.getInteriorFrame().getRightPage();
parentNode.releaseWriteLatch(true);
writeLatched = false;
bufferCache.unpin(parentNode);
if (rightPage == -1) {
break;
}
parentId = rightPage;
parentNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, parentId), false);
parentNode.acquireWriteLatch();
writeLatched = true;
ctx.getInteriorFrame().setPage(parentNode);
}
}
if (foundParent) {
try {
ctx.getInteriorFrame().adjustKey(ctx.getSplitKey().getLeftTuple(), -1, ctx.getCmp());
} catch (Exception e) {
if (writeLatched) {
parentNode.releaseWriteLatch(true);
writeLatched = false;
bufferCache.unpin(parentNode);
}
throw e;
}
insertTuple(parentNode, parentId, ctx.getSplitKey().getRightTuple(), ctx, ctx.getInteriorFrame().isLeaf());
ctx.getPathList().moveLast();
succeeded = true;
return;
}
} finally {
if (!succeeded) {
if (writeLatched) {
parentNode.releaseWriteLatch(true);
writeLatched = false;
bufferCache.unpin(parentNode);
}
}
}
ctx.getTraverseList().clear();
findPath(ctx);
updateParentForInsert(ctx);
}
use of org.apache.hyracks.storage.common.buffercache.ICachedPage in project asterixdb by apache.
the class RTreeSearchCursor method fetchNextLeafPage.
protected boolean fetchNextLeafPage() throws HyracksDataException {
boolean succeeded = false;
if (readLatched) {
page.releaseReadLatch();
bufferCache.unpin(page);
readLatched = false;
}
while (!pathList.isEmpty()) {
int pageId = pathList.getLastPageId();
long parentLsn = pathList.getLastPageLsn();
pathList.moveLast();
if (pageId < 0) {
throw new IllegalStateException();
}
if (fileId < 0) {
throw new IllegalStateException();
}
ICachedPage node = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, pageId), false);
node.acquireReadLatch();
readLatched = true;
try {
interiorFrame.setPage(node);
boolean isLeaf = interiorFrame.isLeaf();
long pageLsn = interiorFrame.getPageLsn();
if (pageId != rootPage && parentLsn < interiorFrame.getPageNsn()) {
// Concurrent split detected, we need to visit the right
// page
int rightPage = interiorFrame.getRightPage();
if (rightPage != -1) {
pathList.add(rightPage, parentLsn, -1);
}
}
if (!isLeaf) {
// (such as Hilbert order)
if (searchKey != null) {
for (int i = interiorFrame.getTupleCount() - 1; i >= 0; i--) {
int childPageId = interiorFrame.getChildPageIdIfIntersect(searchKey, i, cmp);
if (childPageId != -1) {
pathList.add(childPageId, pageLsn, -1);
}
}
} else {
for (int i = interiorFrame.getTupleCount() - 1; i >= 0; i--) {
int childPageId = interiorFrame.getChildPageId(i);
pathList.add(childPageId, pageLsn, -1);
}
}
} else {
page = node;
// This is only needed for the
this.pageId = pageId;
// LSMRTree flush operation
leafFrame.setPage(page);
tupleIndex = 0;
succeeded = true;
return true;
}
} finally {
if (!succeeded) {
if (readLatched) {
node.releaseReadLatch();
readLatched = false;
bufferCache.unpin(node);
}
}
}
}
return false;
}
use of org.apache.hyracks.storage.common.buffercache.ICachedPage in project asterixdb by apache.
the class RTree method findLeaf.
private ICachedPage findLeaf(RTreeOpContext ctx) throws HyracksDataException {
int pageId = rootPage;
boolean writeLatched = false;
boolean readLatched = false;
boolean succeeded = false;
ICachedPage node = null;
boolean isLeaf = false;
long pageLsn = 0, parentLsn = 0;
try {
while (true) {
if (!writeLatched) {
node = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, pageId), false);
ctx.getInteriorFrame().setPage(node);
isLeaf = ctx.getInteriorFrame().isLeaf();
if (isLeaf) {
node.acquireWriteLatch();
writeLatched = true;
if (!ctx.getInteriorFrame().isLeaf()) {
node.releaseWriteLatch(true);
writeLatched = false;
bufferCache.unpin(node);
continue;
}
} else {
// Be optimistic and grab read latch first. We will swap
// it to write latch if we need to enlarge the best
// child tuple.
node.acquireReadLatch();
readLatched = true;
}
}
if (pageId != rootPage && parentLsn < ctx.getInteriorFrame().getPageNsn()) {
// re-choose the best child
if (writeLatched) {
node.releaseWriteLatch(true);
writeLatched = false;
bufferCache.unpin(node);
} else {
node.releaseReadLatch();
readLatched = false;
bufferCache.unpin(node);
}
pageId = ctx.getPathList().getLastPageId();
if (pageId != rootPage) {
parentLsn = ctx.getPathList().getPageLsn(ctx.getPathList().size() - 2);
}
ctx.getPathList().moveLast();
continue;
}
pageLsn = ctx.getInteriorFrame().getPageLsn();
ctx.getPathList().add(pageId, pageLsn, -1);
if (!isLeaf) {
// findBestChild must be called *before* checkIfEnlarementIsNeeded
int childPageId = ctx.getInteriorFrame().findBestChild(ctx.getTuple(), ctx.getCmp());
boolean enlarementIsNeeded = ctx.getInteriorFrame().checkIfEnlarementIsNeeded(ctx.getTuple(), ctx.getCmp());
if (enlarementIsNeeded) {
if (!writeLatched) {
node.releaseReadLatch();
readLatched = false;
bufferCache.unpin(node);
node = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, pageId), false);
node.acquireWriteLatch();
writeLatched = true;
ctx.getInteriorFrame().setPage(node);
if (ctx.getInteriorFrame().getPageLsn() != pageLsn) {
// The page was changed while we unlocked it;
// thus, retry (re-choose best child)
ctx.getPathList().moveLast();
continue;
}
}
// We don't need to reset the frameTuple because it is
// already pointing to the best child
ctx.getInteriorFrame().enlarge(ctx.getTuple(), ctx.getCmp());
node.releaseWriteLatch(true);
writeLatched = false;
bufferCache.unpin(node);
} else {
if (readLatched) {
node.releaseReadLatch();
readLatched = false;
bufferCache.unpin(node);
} else if (writeLatched) {
node.releaseWriteLatch(true);
writeLatched = false;
bufferCache.unpin(node);
}
}
pageId = childPageId;
parentLsn = pageLsn;
} else {
ctx.getLeafFrame().setPage(node);
succeeded = true;
return node;
}
}
} finally {
if (!succeeded) {
if (readLatched) {
node.releaseReadLatch();
readLatched = false;
bufferCache.unpin(node);
} else if (writeLatched) {
node.releaseWriteLatch(true);
writeLatched = false;
bufferCache.unpin(node);
}
}
}
}
use of org.apache.hyracks.storage.common.buffercache.ICachedPage in project asterixdb by apache.
the class RTree method findPath.
private void findPath(RTreeOpContext ctx) throws HyracksDataException {
boolean readLatched = false;
int pageId = rootPage;
int parentIndex = -1;
long parentLsn = 0;
long pageLsn;
int pageIndex;
ICachedPage node = null;
ctx.getTraverseList().add(pageId, -1, parentIndex);
try {
while (!ctx.getTraverseList().isLast()) {
pageId = ctx.getTraverseList().getFirstPageId();
parentIndex = ctx.getTraverseList().getFirstPageIndex();
node = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, pageId), false);
node.acquireReadLatch();
readLatched = true;
ctx.getInteriorFrame().setPage(node);
pageLsn = ctx.getInteriorFrame().getPageLsn();
pageIndex = ctx.getTraverseList().first();
ctx.getTraverseList().setPageLsn(pageIndex, pageLsn);
ctx.getTraverseList().moveFirst();
if (ctx.getInteriorFrame().isLeaf()) {
throw HyracksDataException.create(ErrorCode.FAILED_TO_RE_FIND_PARENT);
}
if (pageId != rootPage) {
parentLsn = ctx.getTraverseList().getPageLsn(ctx.getTraverseList().getPageIndex(pageIndex));
}
if (pageId != rootPage && parentLsn < ctx.getInteriorFrame().getPageNsn()) {
int rightPage = ctx.getInteriorFrame().getRightPage();
if (rightPage != -1) {
ctx.getTraverseList().addFirst(rightPage, -1, parentIndex);
}
}
if (ctx.getInteriorFrame().findTupleByPointer(ctx.getSplitKey().getLeftTuple(), ctx.getTraverseList(), pageIndex, ctx.getCmp()) != -1) {
ctx.getPathList().clear();
fillPath(ctx, pageIndex);
return;
}
node.releaseReadLatch();
readLatched = false;
bufferCache.unpin(node);
}
} finally {
if (readLatched) {
node.releaseReadLatch();
readLatched = false;
bufferCache.unpin(node);
}
}
}
use of org.apache.hyracks.storage.common.buffercache.ICachedPage in project asterixdb by apache.
the class VirtualFreePageManager method isEmpty.
@Override
public boolean isEmpty(ITreeIndexFrame frame, int rootPage) throws HyracksDataException {
ICachedPage rootNode = bufferCache.pin(BufferedFileHandle.getDiskPageId(fileId, rootPage), false);
rootNode.acquireReadLatch();
try {
frame.setPage(rootNode);
return frame.getLevel() == 0 && frame.getTupleCount() == 0;
} finally {
rootNode.releaseReadLatch();
bufferCache.unpin(rootNode);
}
}
Aggregations