Package org.chaidb.db.log

Source Code of org.chaidb.db.log.DefaultLogFile

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

import org.apache.log4j.Logger;
import org.chaidb.db.DBState;
import org.chaidb.db.exception.ChaiDBException;
import org.chaidb.db.exception.ErrorCode;
import org.chaidb.db.helper.Config;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;


public class DefaultLogFile extends LogFile {
    private static final Logger logger = Logger.getLogger(DefaultLogFile.class);

    /* log file instance */
    private static DefaultLogFile defaultLogFile = null;

    public static final String CHAIDB_DATALOG_PATH = "chaidb.datalog.path";
    public static final String DEFAULT_DATALOG_DIR_NAME = "datalog";

    /**
     * Default Constructor
     */
    private DefaultLogFile() {
        try {
            init(getDefaultPath());
        } catch (ChaiDBException e) {
            ; //impossible
        }
    }

    /**
     * Get instance
     *
     * @return an instance of LogFile based on default log path
     */
    public static DefaultLogFile getInstance() {
        if (defaultLogFile == null) {
            defaultLogFile = new DefaultLogFile();
        }

        return defaultLogFile;
    }

    private String getDefaultPath() {
        String logPath = null;

        if (((logPath = System.getProperty(CHAIDB_DATALOG_PATH)) != null) && (logPath.length() > 0)) {
            return logPath;
        }

        try {
            logPath = Config.getCurrentDBDirectory() + File.separator + DEFAULT_DATALOG_DIR_NAME;
        } catch (Exception e) {
            logPath = Config.getDbHome() + File.separator + DEFAULT_DATALOG_DIR_NAME;
        }

        return logPath;
    }

    /**
     * get log file name according to Lsn's fileId value
     *
     * @param lsn
     * @return String fileName
     */
    public String getLogFileNameIfExists(Lsn lsn) throws ChaiDBException {
        try {
            int logFileId = lsn.getFileId();
            String fileName = getFileName(logFileId);
            String fileFullName = getFullFileName(logFileId);
            File logFile = new File(fileFullName);

            if (logFile.exists()) {
                return fileName;
            } else {
                return null;
            }
        } catch (Exception e) {
            throw new ChaiDBException(ErrorCode.LOG_ERROR_BASE, e.toString());
        }
    }

    /**
     * write newest fileId to a fileid.idb file
     * 1)if it's the first time to write newest fileId to fileid.idb,
     * create the file and add fileid to it.
     * 2)if file has exist,overwrite the old fileid.
     *
     * @return boolean true|false
     */
    public static boolean writeNewestFileIdToFile(int fileId) throws ChaiDBException {
        if (fileId < LogManager.FIRSTREC_FILEID) {
            return false;
        }

        try {
            DBState.getInstance().setLatestLogFileId((short) fileId);
        } catch (Exception e) {
            logger.debug(e);

            throw new ChaiDBException(ErrorCode.LSN_FILE_IO_ERROR, e.toString());
        }

        return true;
    }

    /**
     * get newest fileId from fileid.idb file
     *
     * @return int fileId
     */
    public static int getNewestFileIdFromStateFile() {
        int fileId = LogManager.FIRSTREC_FILEID;

        try {
            fileId = DBState.getInstance().getLatestLogFileId();

            if (fileId == 0) {
                fileId = LogManager.FIRSTREC_FILEID;
            }
        } catch (Exception e) {
            fileId = LogManager.FIRSTREC_FILEID;
        }

        return fileId;
    }

    /**
     * get the lastest lsn in fileid.idb file
     *
     * @return Lsn lastLsn
     */
    public Lsn getLastLsnInDir(int[] endOffset) throws ChaiDBException {
        int fileId = getNewestFileIdFromStateFile();

        return getLastLsn(fileId, endOffset);
    }

    /**
     * get first log record bytes of all files, no use
     *
     * @return byte[] logRecord byte array
     */
    public LogRecord getFirstLogRecord() throws ChaiDBException {
        Lsn lsn = getFirstLsn();
        LogRecord logObj = getLogRecordByLsn(lsn);

        return logObj;
    }

    /**
     * get latest log record bytes of all files, no use
     *
     * @return byte[] logRecord byte array
     */
    public LogRecord getLastestLogRecord() throws ChaiDBException {
        int[] endOffset = new int[1];
        Lsn lsn = getLastLsnInDir(endOffset);
        LogRecord logObj = getLogRecordByLsn(lsn);

        return logObj;
    }

    /**
     * get a log record from log file by input lsn,//it's not used,just for test
     *
     * @param lsn
     * @return LogRecord object
     */
    public LogRecord getLogRecordByLsn(Lsn lsn) throws ChaiDBException {
        int fileId = lsn.getFileId();
        int offset = lsn.getOffset();
        int hdrLen = Hdr.getHdrLength();
        int fileLen = getDefaultLogFileLength(fileId);

        if ((fileLen == 0) || (offset > fileLen)) {
            throw new ChaiDBException(ErrorCode.LOG_RECORD_NOT_EXIST);
        }

        RandomAccessFile rfile = null;

        try {
            rfile = open(fileId, "r");

            /* get the record header(Hdr) */
            byte[] hdrArr = new byte[hdrLen];
            rfile.seek(offset);
            rfile.read(hdrArr, 0, hdrLen);

            Hdr hdr = new Hdr();

            if (hdr.read(hdrArr, 0)) {
                int logRecLen = hdr.getLength();
                byte[] logObjArr = new byte[logRecLen];
                rfile.seek(offset);
                rfile.read(logObjArr, 0, logRecLen);

                return RecordFactory.createRecord(logObjArr, 0);
            } else {
                throw new ChaiDBException(ErrorCode.LOG_RECORD_HEADER_CANNOT_READ);
            }
        } catch (IOException ie) {
            throw new ChaiDBException(ErrorCode.LOG_FILE_IO_ERROR, ie);
        } finally {
            if (rfile != null) {
                try {
                    rfile.close();
                } catch (IOException e) {
                    throw new ChaiDBException(ErrorCode.LOG_FILE_IO_ERROR, e);
                }
            }
        }
    }

    /**
     * get log file's length, only called by getLogRecordByLsn, for test purpose
     *
     * @param fileId
     * @return int fileLen
     */
    public int getDefaultLogFileLength(int fileId) {
        if (fileId <= 0) {
            return 0;
        }

        int fileLen = 0;
        String fileName = getFullFileName(fileId);
        File logFile = new File(fileName);

        if (logFile.exists()) {
            fileLen = new Long(logFile.length()).intValue();

            if (fileLen > Lsn.getLsnLength()) {
                /*subtract lastest lsn length in log file,modified by marriane 2001-11-27*/
                if (fileId == getNewestFileIdFromStateFile()) {
                    fileLen = fileLen - Lsn.getLsnLength();
                }
            } else {
                fileLen = 0;
            }
        } else {
            fileLen = 0;
        }

        return fileLen;
    }

    protected void changeWriteFile(int fileId, int offset) throws ChaiDBException {
        super.changeWriteFile(fileId, offset);
        writeNewestFileIdToFile(fileId);
    }
}
TOP

Related Classes of org.chaidb.db.log.DefaultLogFile

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.