Package org.chaidb.db.index.btree

Source Code of org.chaidb.db.index.btree.Id2nodeBTreeEnumerator

/*
* 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.KernelContext;
import org.chaidb.db.exception.ChaiDBException;
import org.chaidb.db.helper.ByteTool;
import org.chaidb.db.index.IDBIndex;
import org.chaidb.db.index.Key;
import org.chaidb.db.index.btree.bufmgr.PageBufferManager;
import org.chaidb.db.index.btree.bufmgr.PageNumber;

import java.util.Enumeration;
import java.util.Hashtable;

/**
* This class implements Enumeration, get all keys from Id2nodeBTree.
* User: arefool
* Date: Mar 14, 2003
* Time: 3:51:31 PM
*/
public class Id2nodeBTreeEnumerator implements TreeEnumerator {

    private IBTree btree;

    private BTreeSpec btreeSpec;
    private PageBufferManager buffer;
    /**
     * specify the current leaf page number
     */
    private PageNumber currentPageNumber;
    /**
     * indicate the next node index in the leaf page
     */
    private int nextNodeIndex;

    /**
     * KernelContext create this enumerator
     */
    private KernelContext kContext;

    /**
     * BTree enumerator for the special tree
     */
    private Enumeration beForSpecialTree;

    //this is only for Special BTree, containing visited document root.
    private Hashtable visitedRoot;
    private Enumeration enumId2root;

    public Id2nodeBTreeEnumerator() {
    }

    /**
     * Constructor
     */
    public Id2nodeBTreeEnumerator(IBTree bt, BTreeSpec btSpec, PageBufferManager buffer, KernelContext kContext) throws ChaiDBException {
        initParameter(bt, btSpec, buffer, kContext);
        init();
    }

    protected void initParameter(IBTree bt, BTreeSpec btSpec, PageBufferManager buffer, KernelContext kContext) {
        setBtree(bt);
        setBtreeSpec(btSpec);
        this.setBuffer(buffer);
        setCurrentPageNumber(new PageNumber());
        this.setkContext(kContext);
    }

    protected void init() throws ChaiDBException {
        PageNumber root = null;

        root = getFirstSubTreeRoot();
        setVisitedRoot(new Hashtable());
        setEnumId2root(((Id2nodeBTree) getBtree()).id2root.elements());

        if (root == null) {
            setCurrentPageNumber(new PageNumber(getBtree().getBtreeId(), 0, -1));
            return;
        }
        //remember visited root
        getVisitedRoot().put(root, root);

        TreeEnumeratorUtils.findLeftMostLeaf(this, root);
    }

    public boolean hasMoreElements() {
        try {
            while (true) {
                if (getCurrentPageNumber().getPageNumber() < 0) {
                    //if it's special, get the next sub tree root
                    if (getBeForSpecialTree().hasMoreElements()) {
                        ((Id2nodeBTree) getBtree()).indexBTree.acquire(kContext, IDBIndex.READ_MODE);
                        byte[] bRoot = (byte[]) ((Id2nodeBTree) getBtree()).indexBTree.lookup((Key) getBeForSpecialTree().nextElement(), getkContext());
                        ((Id2nodeBTree) getBtree()).indexBTree.release(kContext);
                        PageNumber subroot = new PageNumber(ByteTool.bytesToInt(bRoot, 0, getBtreeSpec().isMsbFirst()));
                        subroot.setTreeId(getBtree().getBtreeId());
                        //remember visited root
                        getVisitedRoot().put(subroot, subroot);
                        TreeEnumeratorUtils.findLeftMostLeaf(this, subroot);
                    } else {
                        //return false;
                        boolean notFound = true;
                        while (getEnumId2root().hasMoreElements()) {
                            PageNumber subroot = (PageNumber) getEnumId2root().nextElement();
                            if (!getVisitedRoot().containsKey(subroot)) {
                                TreeEnumeratorUtils.findLeftMostLeaf(this, subroot);
                                getVisitedRoot().put(subroot, subroot);
                                notFound = false;
                                break;
                            }
                        }
                        if (notFound) return false;
                    }

                }

                BTreePage leafPage = new BTreePage(getBtree().getBtreeId(), getCurrentPageNumber(), getBtreeSpec(), getBuffer());

                // unfix the leaf page
                getBuffer().releasePage(getBtree().getBtreeId(), leafPage.pageNumber, false);
                // if current node index is at the end of the page,
                // and there is no successing leaf page after the current one, return false
                int nodes = leafPage.getCurrNodeNumbers();

                if (getNextNodeIndex() >= nodes) {
                    if (leafPage.nextPage.getPageNumber() > 0) setNextNodeIndex(0);
                    getCurrentPageNumber().setPageNumber(leafPage.nextPage);
                } else return true;

            }
        } catch (Exception e) {
            return false;
        }
    }

    public Object nextElement() {
        return TreeEnumeratorUtils.nextElement(this);
    }

    /**
     * Get the first sub tree's root in a forest
     */
    //(id2node.idb)
    protected PageNumber getFirstSubTreeRoot() throws ChaiDBException {
        ((Id2nodeBTree) getBtree()).indexBTree.acquire(kContext, IDBIndex.READ_MODE);
        setBeForSpecialTree(((Id2nodeBTree) getBtree()).indexBTree.keys(getkContext()));
        ((Id2nodeBTree) getBtree()).indexBTree.release(kContext);
        if (getBeForSpecialTree().hasMoreElements()) {
            ((Id2nodeBTree) getBtree()).indexBTree.acquire(kContext, IDBIndex.READ_MODE);
            byte[] bRoot = (byte[]) ((Id2nodeBTree) getBtree()).indexBTree.lookup((Key) getBeForSpecialTree().nextElement(), getkContext());
            ((Id2nodeBTree) getBtree()).indexBTree.release(kContext);
            PageNumber subroot = new PageNumber(ByteTool.bytesToInt(bRoot, 0, getBtreeSpec().isMsbFirst()));
            subroot.setTreeId(getBtree().getBtreeId());
            return subroot;
        }
        return null;
    }

    public IBTree getBtree() {
        return btree;
    }

    public void setBtree(IBTree btree) {
        this.btree = btree;
    }

    public BTreeSpec getBtreeSpec() {
        return btreeSpec;
    }

    public void setBtreeSpec(BTreeSpec btreeSpec) {
        this.btreeSpec = btreeSpec;
    }

    public PageBufferManager getBuffer() {
        return buffer;
    }

    public void setBuffer(PageBufferManager buffer) {
        this.buffer = buffer;
    }

    public PageNumber getCurrentPageNumber() {
        return currentPageNumber;
    }

    public void setCurrentPageNumber(PageNumber currentPageNumber) {
        this.currentPageNumber = currentPageNumber;
    }

    public int getNextNodeIndex() {
        return nextNodeIndex;
    }

    public void setNextNodeIndex(int nextNodeIndex) {
        this.nextNodeIndex = nextNodeIndex;
    }

    public KernelContext getkContext() {
        return kContext;
    }

    public void setkContext(KernelContext kContext) {
        this.kContext = kContext;
    }

    public Enumeration getBeForSpecialTree() {
        return beForSpecialTree;
    }

    public void setBeForSpecialTree(Enumeration beForSpecialTree) {
        this.beForSpecialTree = beForSpecialTree;
    }

    public Hashtable getVisitedRoot() {
        return visitedRoot;
    }

    public void setVisitedRoot(Hashtable visitedRoot) {
        this.visitedRoot = visitedRoot;
    }

    public Enumeration getEnumId2root() {
        return enumId2root;
    }

    public void setEnumId2root(Enumeration enumId2root) {
        this.enumId2root = enumId2root;
    }
}
TOP

Related Classes of org.chaidb.db.index.btree.Id2nodeBTreeEnumerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.