Package org.chaidb.db.index.btree.hbt

Source Code of org.chaidb.db.index.btree.hbt.HyperBTreeIterator

/*
* 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.hbt;

import org.apache.log4j.Logger;
import org.chaidb.db.KernelContext;
import org.chaidb.db.api.DuplicatedKeyIterator;
import org.chaidb.db.exception.ChaiDBException;
import org.chaidb.db.helper.ByteTool;
import org.chaidb.db.index.btree.AbstractBTree;
import org.chaidb.db.index.btree.BTreeSpec;
import org.chaidb.db.index.btree.DataNode;
import org.chaidb.db.index.btree.DataPage;
import org.chaidb.db.index.btree.bufmgr.PageBufferManager;
import org.chaidb.db.index.btree.bufmgr.PageNumber;


abstract class HyperBTreeIterator implements DuplicatedKeyIterator {

    private static final Logger logger = Logger.getLogger(HyperBTreeIterator.class);

    private static boolean useCachedIterator = getUseCache();

    private static boolean getUseCache() {
        boolean ret = true;
        String prtStr = System.getProperty("chaidb.hbt.cachediterator");
        if (prtStr != null && prtStr.equalsIgnoreCase("false")) {
            ret = false;
        }
        return ret;
    }

    protected AbstractBTree btree;
    protected KernelContext kContext;
    protected boolean finished;
    protected NodeInfo _nextNode;
    protected NodeInfo _prevNode = new NodeInfo();
    protected NodeInfo _curNode = new NodeInfo();

    static final int DUP_DATA = 0x01;
    static final int DUP_NEXT = 0x02;
    static final int DUP_FINISHED = 0x04;
    static final int DUP_FAILED = 0x80;


    HyperBTreeIterator(AbstractBTree btree, KernelContext kContext) {
        this.btree = btree;
        this.kContext = kContext;
    }

    static HyperBTreeIterator createIterator(AbstractBTree btree, KernelContext kContext) {
        if (useCachedIterator) {
            return new HyperBTreeCachedIterator(btree, kContext);
        } else {
            return new HyperBTreeBasicIterator(btree, kContext);
        }
    }

    void initIterator(NodePosition firstNode) {
        _nextNode = new NodeInfo();
        _nextNode.nodeNextPosition = firstNode;
    }

    /**
     * To update a dup_next node to point to a new position
     *
     * @param nodePos     the position of dup_next node
     * @param nextNodePos the new position which dup_next will point to
     */
    protected void updateDupNextNode(NodePosition nodePos, NodePosition nextNodePos) {
        if (nodePos == null) return;

        if (nextNodePos == null) {
            nextNodePos = nodePos;
        }

        final PageBufferManager buffer = btree.getBuffer();
        final BTreeSpec btreeSpec = btree.getBTreeSpec();
        PageNumber dupPageNumber = new PageNumber(nodePos.getPageNo());
        try {
            DataPage curDataPage = new DataPage(btree.getBtreeId(), dupPageNumber, btreeSpec, buffer);
            DataNode curDataNode = new DataNode(curDataPage, nodePos.getOffsetInPage());
            curDataNode.setFlags(BTreeSpec.DATA_NODE_DUP_NEXT);
            byte[] oldData = ByteTool.copyByteArray(curDataNode.getPage().getPage(), curDataNode.getNodeOffset(), (int) curDataNode.getNodeSpace());
            byte[] data = new byte[8];
            ByteTool.intToBytes(data, 0, nextNodePos.getOffsetInPage());
            ByteTool.intToBytes(data, 4, nextNodePos.getPageNo());
            curDataNode.storeNode(data, oldData, kContext);
            buffer.releasePage(btree.getBtreeId(), nodePos.getPageNo(), true);
        } catch (ChaiDBException e) {
            logger.error(e);
            buffer.releasePage(btree.getBtreeId(), nodePos.getPageNo(), false);
        }
    }

    protected void removeOneNode(NodePosition prevNodeNextPos, NodeInfo curNode, NodePosition nextNodePos) {
        if (prevNodeNextPos == null || prevNodeNextPos.equals(curNode.nodePosition)) {
            updateDupNextNode(curNode.nodePosition, nextNodePos);
        } else {
            updateDupNextNode(prevNodeNextPos, nextNodePos);
        }
        curNode.nodeNextPosition = prevNodeNextPos;
    }

    /**
     * Get a node located at node.nodePosition
     *
     * @return 0x80 - failed
     *         0x1 - dupdata
     *         0x2 - dupnext
     *         0x4 - finished
     *         node.nodeNextPosition is updated to the next position after the node,
     *         if the node is dup_next, nodeNextPosition stored the pointer. if link
     *         is end, nodeNextPosition will be null.
     */
    protected int getNode(DataPage dataPage, NodeInfo node) {
        DataNode dupDataNode = new DataNode(dataPage, node.nodePosition.getOffsetInPage());
        int nPageNo = node.nodePosition.getPageNo();
        int nOffset = node.nodePosition.getOffsetInPage();

        try {
            byte[] data = dupDataNode.getData();
            if (dupDataNode.isDupData()) {
                //This node is available value
                node.data = btree.decodeFromByteArray(data, null);
                node.nodeNextPosition = new NodePosition(nPageNo, nOffset + dupDataNode.getNodeSpace());
                return DUP_DATA;
            } else if (dupDataNode.isDupNext()) {
                node.data = null;
                int nextOffset = ByteTool.bytesToInt(data, 0, btree.getBTreeSpec().isMsbFirst());
                int nNextPageNumber = ByteTool.bytesToInt(data, 4, btree.getBTreeSpec().isMsbFirst());
                if ((nextOffset == nOffset) && (nNextPageNumber == nPageNo)) {
                    node.nodeNextPosition = null;
                    return DUP_NEXT | DUP_FINISHED;
                }
                node.nodeNextPosition = new NodePosition(nNextPageNumber, nextOffset);
                return DUP_NEXT;
            } else {
                node.data = btree.decodeFromByteArray(data, null);
                node.nodeNextPosition = null;
                return DUP_DATA | DUP_FINISHED;
            }
        } catch (ChaiDBException e) {
            logger.error(e);
        }
        return DUP_FAILED;
    }

    public void remove() {
        NodePosition prevPos = null;
        NodePosition nextPos = null;

        if (_prevNode != null) {
            prevPos = _prevNode.nodeNextPosition;
        }

        if (_nextNode != null) {
            nextPos = _nextNode.nodePosition;
        }

        removeOneNode(prevPos, _curNode, nextPos);
    }

    public void close() {
    }

}
TOP

Related Classes of org.chaidb.db.index.btree.hbt.HyperBTreeIterator

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.