try {
// fix the page
page = buffer.getPage(pageNumber.getTreeId(), pageNumber);
if (page == null)
throw new ChaiDBException(ErrorCode.BTREE_INVALID_BTREEPAGE, "Page is null: " + pageNumber.toHexString() + " of " + btreeSpec.getBtreeName());
if (Debug.DEBUG_CHECKPAGENUMBER) {
if (!Debug.checkPageNumber(pageNumber, this.page)) {
logger.fatal(new Throwable("there is hole in GetPage!"));
this.buffer.dump();
Db.getLogManager().flush();
Debug.dumpPageToLog(page);
if (Debug.DEBUG_PAGEINFO_TRACE) Debug.pageHistory(this.pageNumber);
System.exit(-1);
}
}
// Binary search within page
int nodeIndexFirst = 0;
int nodeIndexLast = getCurrNodeNumbers() - 1;
while (nodeIndexLast > nodeIndexFirst) {
int nodeIndex = (nodeIndexFirst + nodeIndexLast) / 2;
BTreeNode node = getNode(nodeIndex);
/* Modified by ben zhang at aug, 12, 2002 */
Key tmpKey = node.getKey();
int cmp = tmpKey.compareTo(key);
if (cmp > 0) {
nodeIndexLast = nodeIndex - 1;
} else if (cmp < 0) {
nodeIndexFirst = nodeIndex;
if (isLeaf()) nodeIndexFirst++;
else if (nodeIndexLast - nodeIndexFirst == 1) {
BTreeNode node2 = getNode(nodeIndexLast);
/*Modified by ben zhang at aug, 12, 2002 */
tmpKey = node2.getKey();
int cmpResult = tmpKey.compareTo(key);
if (cmpResult > 0) {
BTreePage page = this.lockAPage(kContext, node.getPageNumber(), SEARCH);
// unfix the current page
buffer.releasePage(pageNumber.getTreeId(), pageNumber, false);
returnNode = page.search(key, kContext);
// unfix the current page
buffer.releasePage(btreeSpec.btree.getBtreeId(), page.pageNumber, false);
return returnNode;
} else {
BTreePage page = this.lockAPage(kContext, node2.getPageNumber(), SEARCH);
// unfix the current page
buffer.releasePage(pageNumber.getTreeId(), pageNumber, false);
returnNode = page.search(key, kContext);
// unfix the current page
buffer.releasePage(btreeSpec.btree.getBtreeId(), page.pageNumber, false);
return returnNode;
}
}
} else { // Exact match
if (isLeaf()) {
return node;
}
BTreePage page = this.lockAPage(kContext, node.getPageNumber(), SEARCH);
// unfix the current page
buffer.releasePage(pageNumber.getTreeId(), pageNumber, false);
returnNode = page.search(key, kContext);
// unfix the new allocated page
buffer.releasePage(btreeSpec.btree.getBtreeId(), page.pageNumber, false);
return returnNode;
}
} // end of binary search
if (!isLeaf() && nodeIndexFirst - nodeIndexLast == 1) {
// go to leftmost node
if (nextPage.getPageNumber() > 0) {
BTreePage page = this.lockAPage(kContext, nextPage, SEARCH);
// unfix current page
buffer.releasePage(pageNumber.getTreeId(), pageNumber, false);
returnNode = page.search(key, kContext);
// unfix the new allocated page
buffer.releasePage(btreeSpec.btree.getBtreeId(), page.pageNumber, false);
return returnNode;
} else {
logger.error("Page " + pageNumber.toHexString() + " " + buffer.getBTreeName(pageNumber.getTreeId()) + " missing leftmost page " + Debug.getDebugInfo());
//Debug.pageHistory(Integer.toHexString(pageNumber.getPageNumber()));
Debug.flushPages();
if (Debug.DEBUG_THREAD) Debug.flushThreads();
// details -ranjeet
String details = "The page number is " + pageNumber.toHexString() + ".";
throw new ChaiDBException(ErrorCode.BTREE_LEFTMOST_PAGE_MISSING, details);
}
}
// now binary search has identified a single node
// node.setTreeId(btreeSpec.btree.getBtreeId());
// Leaf node? need an exact match to avoid failure
if (isLeaf()) {
BTreeNode node = getNode(nodeIndexFirst);
//buffer.releasePage(pageNumber.getTreeId() ,pageNumber, false);
/*Modified by ben zhang at aug, 12, 2002 */
if (node != null && node.getKey().compareTo(key) == 0) return node;
else {
//release it for outside this method, this page can't be found any longer.
buffer.releasePage(pageNumber.getTreeId(), pageNumber, false);
return null;
}
} else {
BTreeNode node = getNode(nodeIndexFirst);
/*Modified by ben zhang at aug, 12, 2002 */
Key tmpKey = node.getKey();
int cmp = key.compareTo(tmpKey);
if (cmp < 0) {
// go to leftmost pointer
if (nextPage.getPageNumber() > 0) {
BTreePage page = this.lockAPage(kContext, nextPage, SEARCH);
// unfix current page
buffer.releasePage(pageNumber.getTreeId(), pageNumber, false);
returnNode = page.search(key, kContext);
// unfix the new allocated page
buffer.releasePage(btreeSpec.btree.getBtreeId(), page.pageNumber, false);
return returnNode;
} else {
logger.error("Page " + pageNumber + " missing leftmost page " + Debug.getDebugInfo());
//Debug.pageHistory(Integer.toHexString(pageNumber.getPageNumber()));
Debug.flushPages();
if (Debug.DEBUG_THREAD) Debug.flushThreads();
// details -ranjeet
String details = "The page number is " + pageNumber.getPageNumber() + ".";
throw new ChaiDBException(ErrorCode.BTREE_LEFTMOST_PAGE_MISSING, details);
}
}
BTreePage page = this.lockAPage(kContext, node.getPageNumber(), SEARCH);
// unfix the current page