Package org.chaidb.db.log.logrecord

Source Code of org.chaidb.db.log.logrecord.BTreeSpecLogRecord

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

import org.apache.log4j.Logger;
import org.chaidb.db.Db;
import org.chaidb.db.exception.ChaiDBException;
import org.chaidb.db.helper.ByteTool;
import org.chaidb.db.index.btree.BTree;
import org.chaidb.db.index.btree.bufmgr.PageBufferManager;
import org.chaidb.db.log.LogManager;
import org.chaidb.db.log.LogRecord;
import org.chaidb.db.log.Lsn;

/**
* BTREE-spec: used to log the modification of BTreeSpec.
* <p/>
* pgno:  the page modified.
* lsn:    the page's original lsn.
* orig:  the original data.
* new:    the replacement data.
* duplicate:  the prefix of the replacement that matches the original.
*/
public class BTreeSpecLogRecord extends LogRecord {
    private static PageBufferManager bpm = PageBufferManager.getInstance();
    private static final Logger logger = Logger.getLogger(BTreeSpecLogRecord.class);
    private int treeId;
    private int oldPageNum;
    private int newPageNum;
    private byte flag;        //replace data flag of BTreeSpec
    private byte[] docIdArr = null; //added by marriane 2002-1-31 for one doc one btree
    //    private byte[] bUdiKey = null; //added by marriane 2002-1-31 for one doc one btree
    private int udiKeyType = 0;
    //    private Key udiKey = null;
    /* Appended by Arefool at 2003/3/25 for support Hyper Btree*/
    private short btreeType;

    //    private static final int UDI_KEY_LEN_SIZE = 4;
    private static final int FLAG_SIZE = 1; //1 bytes
    private static final int BTREE_TYPE_SIZE = 1; //1 byte

    //public static final byte RECORD_COUNT_FLAG = 1 ;
    public static final byte PAGE_NUMBER_FLAG = 1;
    public static final byte ROOT_PAGE_NUMBER_FLAG = 2;
    public static final byte LATEST_DATA_PAGE_NUMBER_FLAG = 3;
    public static final byte DOC_ROOT_PAGE_NUMBER_FLAG = 4;
    /* Appended by ben at Aug, 06, 2002 for supporting flexible node size */
    public static final byte NODE_SIZE_FLAG = 5;
    public static final byte LAYER_FLAG = 6;
    /* Appended by ben zhang at aug, 06, 2002 for supporting key type. */
    public static final byte KEY_TYPE_FLAG = 7;

    /**
     * Default Constructor
     */
    public BTreeSpecLogRecord() {
        setType(LOG_BTREE_SPEC);
    }

    /**
     * Constructor
     *
     * @param treeId
     * @param oldPageNum
     * @param newPageNum
     * @param flag
     * @param txnId
     */
    public BTreeSpecLogRecord(int treeId, int oldPageNum, int newPageNum, byte flag, int txnId, short btreeType) {
        super();
        super.setTxnId(txnId);
        super.setType(LOG_BTREE_SPEC);

        this.treeId = treeId;
        this.oldPageNum = oldPageNum;
        this.newPageNum = newPageNum;
        this.flag = flag;
        this.docIdArr = null;
//        this.udiKey = null;
        this.btreeType = btreeType;
    }


    /**
     * Constructor
     *
     * @param treeId
     * @param oldPageNum
     * @param newPageNum
     * @param flag
     * @param txnId
     * @param docid
     */
    public BTreeSpecLogRecord(int treeId, int oldPageNum, int newPageNum, byte flag, int txnId, int docid, short btreeType) {
        super();
        super.setTxnId(txnId);
        super.setType(LOG_BTREE_SPEC);

        this.treeId = treeId;
        this.oldPageNum = oldPageNum;
        this.newPageNum = newPageNum;
        this.flag = flag;

        byte[] docId = ByteTool.intToBytes(docid);
        docId = ByteTool.subByteArray(docId, docId.length - BTree.DOCID_SIZE, BTree.DOCID_SIZE);

        this.docIdArr = docId;
        this.btreeType = btreeType;
    }

    /**
     * get flag of current BTreeSpecLogRecord Object
     *
     * @return int flag
     */
    public byte getFlag() {
        return flag;
    }

    /**
     * get docIdArray
     * if flag<4,return null
     */
    public byte[] getDocIdArray() {
        if (docIdArr != null) return ByteTool.copyByteArray(docIdArr, 0, docIdArr.length);
        else return null;
    }

    public short getBtreeType() {
        return btreeType;
    }

    public int getTreeId() {
        return treeId;
    }

    public int getOldPageNum() {
        return oldPageNum;
    }

    public int getNewPageNum() {
        return newPageNum;
    }

    public int getUdiKeyType() {
        return udiKeyType;
    }

    /**
     * user interface to add a log record and put it to buffer pool
     */
    public Lsn log() throws ChaiDBException {
        super.log();
        LogManager logMgr = Db.getLogManager();
        Lsn newLsn = logMgr.put(this, LogManager.LOG_DATA);

        return newLsn;
    }


    /**
     * converts a byte array into a log record instance
     */
    public boolean read(byte[] bArr, int start) throws ChaiDBException {
        /* construct a new LogRecord instance */
        super.read(bArr, start);

        /* get the values of BTreeSpecLogRecord Object */
        int step = start + super.getRecordLength();
        treeId = ByteTool.bytesToInt(bArr, step, msbFirst);
        step += BTreeLogRecord.TREEID_SIZE;
        oldPageNum = ByteTool.bytesToInt(bArr, step, msbFirst);
        step += BTreeLogRecord.PAGENUM_SIZE;
        newPageNum = ByteTool.bytesToInt(bArr, step, msbFirst);
        step += BTreeLogRecord.PAGENUM_SIZE;
        flag = bArr[step];
        step += FLAG_SIZE;
        btreeType = (short) bArr[step];
        step += BTREE_TYPE_SIZE;

        if (flag == DOC_ROOT_PAGE_NUMBER_FLAG || flag == LATEST_DATA_PAGE_NUMBER_FLAG) {

            docIdArr = new byte[BTree.DOCID_SIZE];
            System.arraycopy(bArr, step, docIdArr, 0, BTree.DOCID_SIZE);
        }
        return true;
    }

    /**
     * redo
     *
     * @return boolean true|false
     */
    protected boolean doRedo() throws ChaiDBException {
        PageBufferManager bp = bpm;
        return bp.updateBTreeSpec(treeId, newPageNum, flag, new Integer(super.getTxnId()), docIdArr, this.btreeType);

    }

    /**
     * undo
     *
     * @return boolean true|false
     */
    protected boolean doUndo() throws ChaiDBException {
        /* needn't do undo while flag is PAGE_NUMBER_FLAG or LATEST_DATA_PAGE_NUMBER_FLAG,
           because the first free page number or latest datapage number still is
           the value of replaceData while the page is added to freelist */

        if (flag == PAGE_NUMBER_FLAG || flag == LATEST_DATA_PAGE_NUMBER_FLAG || flag == LAYER_FLAG || //by leon
                flag == KEY_TYPE_FLAG || //by ben zhang
                /* needn't do undo while flag is NODE_SIZE_FLAG, because
                it is not meaning. ?!*/
                flag == NODE_SIZE_FLAG) //appended by ben at Aug, 06, 2002
            return false;

        PageBufferManager bp = bpm;
        return bp.updateBTreeSpec(treeId, oldPageNum, flag, new Integer(super.getTxnId()), docIdArr, this.btreeType);
    }

    /**
     * redo or undo the operation for recovery
     *
     * @param flag REDO or UNDO.
     * @return
     * @throws ChaiDBException
     */
    public boolean recover(short flag) throws ChaiDBException {

        /* To see updates have been written to disk already.
         * if REDO and lsn>pageLsn or UNDO and lsn<pageLsn, the operation has
         * not been updated to disk and redo/undo is necessary.
         */
        if (flag == REDO) {
            return doRedo();
        } else if (flag == UNDO) {
            return doUndo();
        }
        return true;
    }

    /**
     * print data and help in debugging log files
     */
    public void print() throws ChaiDBException {
        //logger.debug("begin: printing the information of BTreeSpecLogRecord object......");
        super.print();
        logger.debug("treeId:" + treeId);
        /* Modified by ben at Aug, 06, 2002 */
        if (flag != 5 && flag != 6 && flag != 7) {
            logger.debug("oldPageNum:" + oldPageNum);
            logger.debug("newPageNum:" + newPageNum);
        } else if (flag == 5) {
            logger.debug("old node size:" + oldPageNum);
            logger.debug("new node size:" + newPageNum);
        } else if (flag == 6) {
            logger.debug("old layer size:" + oldPageNum);
            logger.debug("new layer size:" + newPageNum);
        } else if (flag == 7) {
            logger.debug("old key size:" + oldPageNum);
            logger.debug("new key size:" + newPageNum);
        }
        if (flag == 1) {
            logger.debug("flag:1 VALID_FREE_PAGE_NUM");
        } else if (flag == 2) {
            logger.debug("flag:2 ROOT_PAGE_NUM");
        } else if (flag == 3) {
            logger.debug("flag:3 LATEST_DATAPAGE_NUM");
        } else if (flag == 4) {
            logger.debug("flag:4 DOC_ROOT_PAGE_NUM");
        } else if (flag == 5) {/* APPENDED by ben at Aug, 06, 2002 for supporting flexible node size. */
            logger.debug("flag:5 NODE_SIZE");
        } else if (flag == 6) {
            logger.debug("flag:6 LAYER");
        } else if (flag == 7) {
            logger.debug("flag:7 KEY_SIZE");
        } else if (flag == 8) {
            logger.debug("flag:8 UDI_KEY_PAGE_NUMBER");
        }

        if (flag == LATEST_DATA_PAGE_NUMBER_FLAG) {
            byte[] tmp = new byte[4];
            System.arraycopy(docIdArr, 0, tmp, tmp.length - BTree.DOCID_SIZE, BTree.DOCID_SIZE);
            logger.debug("docid=" + ByteTool.bytesToInt(tmp, 0, LogRecord.msbFirst));
        }

        //logger.debug("end: printing the information of BTreeSpecLogRecord object.");
    }

    /**
     * converts a log record instance into a byte array.
     * The byte array has the following format:
     * -------------------------------------------------------------------------------
     * | hdr | type | txn | prevLsn | BTreeLogRecord length | offset | prefix | suffix|
     * -------------------------------------------------------------------------------
     * | orgSize | orgData | replSize | replData | flag
     * -------------------------------------------------
     * hdr: 8 bytes,the byte array of the header,generated by Hdr.toBytes().
     * type:    1 bytes.
     * txnId:   4 bytes.
     * prevLsn: 8 bytes,the byte array of the header of lsn,generated by Lsn.toBytes().
     * <p/>
     * fileNameLen 2 bytes
     * fileName    fileNameLen bytes
     * oldPageNum  4 bytes
     * newPageNum  4 bytes
     * flag:       1 byte
     * docIdArr:   3 bytes if flag is more than 3.
     */
    public void toBytes(byte[] byteArray, int start) throws ChaiDBException {
        super.toBytes(byteArray, start);
        int step = start + super.getRecordLength();

        ByteTool.intToBytes(byteArray, step, treeId, msbFirst);
        step += BTreeLogRecord.TREEID_SIZE;

        ByteTool.intToBytes(byteArray, step, oldPageNum, msbFirst);
        step += BTreeLogRecord.PAGENUM_SIZE;

        ByteTool.intToBytes(byteArray, step, newPageNum, msbFirst);
        step += BTreeLogRecord.PAGENUM_SIZE;

        byteArray[step] = flag;
        step += FLAG_SIZE;

        byteArray[step] = (byte) btreeType;
        step += BTREE_TYPE_SIZE;

        if (flag == DOC_ROOT_PAGE_NUMBER_FLAG || flag == LATEST_DATA_PAGE_NUMBER_FLAG) {
            System.arraycopy(docIdArr, 0, byteArray, step, BTree.DOCID_SIZE);
            step += BTree.DOCID_SIZE;
        }
    }


    /**
     * get current log record type total length
     *
     * @return int total lenth
     */
    public int getRecordLength() {
        int len = super.getRecordLength() + BTreeLogRecord.TREEID_SIZE + BTreeLogRecord.PAGENUM_SIZE * 2 + FLAG_SIZE + BTREE_TYPE_SIZE;
        if (flag == DOC_ROOT_PAGE_NUMBER_FLAG || flag == LATEST_DATA_PAGE_NUMBER_FLAG) {

            len += BTree.DOCID_SIZE;
        }
        return len;
    }
}
TOP

Related Classes of org.chaidb.db.log.logrecord.BTreeSpecLogRecord

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.