/*
* Copyright (C) 2006 http://www.chaidb.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
package org.chaidb.db.index.btree;
import org.chaidb.db.exception.ChaiDBException;
import org.chaidb.db.index.Key;
import org.chaidb.db.index.btree.bufmgr.PageNumber;
import java.util.NoSuchElementException;
/**
* User: arefool
* Date: Mar 15, 2003
* Time: 3:12:57 PM
*/
public class TreeEnumeratorUtils {
public static void findLeftMostLeaf(TreeEnumerator treeEnumerator, PageNumber root) throws ChaiDBException {
BTreePage rootPage = new BTreePage(treeEnumerator.getBtree().getBtreeId(), root, treeEnumerator.getBtreeSpec(), treeEnumerator.getBuffer());
if (rootPage.getPage() == null) {
treeEnumerator.setCurrentPageNumber(new PageNumber(treeEnumerator.getBtree().getBtreeId(), 0, -1));
return;
}
// unfix the root page
treeEnumerator.getBuffer().releasePage(treeEnumerator.getBtree().getBtreeId(), root, false);
BTreePage page = rootPage;
while (true) {
if (page.isLeaf()) {
treeEnumerator.setCurrentPageNumber(new PageNumber(page.pageNumber));
treeEnumerator.setNextNodeIndex(0);
break;
}
//crabbing lock algorithm: until a new lock is got, old one doesn't be released
page = new BTreePage(treeEnumerator.getBtree().getBtreeId(), page.nextPage, treeEnumerator.getBtreeSpec(), treeEnumerator.getBuffer());
// unfix the page
treeEnumerator.getBuffer().releasePage(treeEnumerator.getBtree().getBtreeId(), page.pageNumber, false);
}
}
public static Object nextElement(TreeEnumerator treeEnumerator) {
try {
BTreePage leafPage = new BTreePage(treeEnumerator.getBtree().getBtreeId(), treeEnumerator.getCurrentPageNumber(), treeEnumerator.getBtreeSpec(), treeEnumerator.getBuffer());
Key key = leafPage.getNode(treeEnumerator.getNextNodeIndex()).getKey();
// unfix the leaf page
treeEnumerator.getBuffer().releasePage(treeEnumerator.getBtree().getBtreeId(), leafPage.pageNumber, false);
treeEnumerator.setNextNodeIndex(treeEnumerator.getNextNodeIndex() + 1);
return key;
} catch (Exception e) {
throw new NoSuchElementException("may this key is deleted by another thread");
}
}
}