⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logfile.java

📁 非常棒的java数据库
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            }
            int sumLength = in.readInt();
            byte[] summary = new byte[sumLength];
            if (sumLength > 0) {
                in.read(summary, 0, sumLength);
            }
            if (diskFile) {
                database.getDataFile().initFromSummary(summary);
            } else {
                database.getIndexFile().initFromSummary(summary);
            }
            break;
        }
        case 'T':
            if (undo) {
                throw Message.getInternalError("cannot undo truncate");
            } else {
                logSystem.addRedoLog(storage, recordId, blockCount, null);
                storage.setRecordCount(0);
                storage.getDiskFile().setPageOwner(recordId / DiskFile.BLOCKS_PER_PAGE, -1);
                logSystem.setLastCommitForSession(sessionId, id, pos);
            }
            break;
        case 'I':
            if (undo) {
                logSystem.addRedoLog(storage, recordId, blockCount, null);
                storage.setRecordCount(storage.getRecordCount() - 1);
            } else {
                logSystem.getOrAddSessionState(sessionId);
                logSystem.addRedoLog(storage, recordId, blockCount, rec);
                storage.setRecordCount(storage.getRecordCount() + 1);
            }
            break;
        case 'D':
            if (undo) {
                logSystem.addRedoLog(storage, recordId, blockCount, rec);
                storage.setRecordCount(storage.getRecordCount() + 1);
            } else {
                logSystem.getOrAddSessionState(sessionId);
                logSystem.addRedoLog(storage, recordId, blockCount, null);
                storage.setRecordCount(storage.getRecordCount() - 1);
            }
            break;
        default:
            throw Message.getInternalError("type=" + type);
        }
        return true;
    }

    public void redoAllGoEnd() throws SQLException {
        boolean readOnly = logSystem.getDatabase().getReadOnly();
        long length = file.length();
        if (length <= FileStore.HEADER_LENGTH) {
            return;
        }
        try {
            int max = (int) (length / BLOCK_SIZE);
            while (true) {
                pos = getBlock();
                database.setProgress(DatabaseEventListener.STATE_RECOVER, fileName, pos, max);
                if ((long) pos * BLOCK_SIZE >= length) {
                    break;
                }
                boolean more = redoOrUndo(false, readOnly);
                if (!more) {
                    break;
                }
            }
            database.setProgress(DatabaseEventListener.STATE_RECOVER, fileName, max, max);
        } catch (SQLException e) {
            database.getTrace(Trace.LOG).debug("Stop reading log file: " + e.getMessage(), e);
            // wrong checksum (at the end of the log file)
        } catch (OutOfMemoryError e) {
            // OutOfMemoryError means not enough memory is allocated to the VM.
            // this is not necessarily at the end of the log file
            throw Message.convert(e);
        } catch (Throwable e) {
            database.getTrace(Trace.LOG).error("Error reading log file (non-fatal)", e);
            // TODO log exception, but mark as 'probably ok'
            // on power loss, sometime there is garbage at the end of the file
            // we stop recovering in this case (checksum mismatch)
        }
        go(pos);
    }

    void go(int pos) throws SQLException {
        file.seek((long) pos * BLOCK_SIZE);
    }

    void undo(int pos) throws SQLException {
        go(pos);
        redoOrUndo(true, false);
    }

    void flush() throws SQLException {
        if (bufferPos > 0) {
            if (file == null) {
                throw Message.getSQLException(ErrorCode.SIMULATED_POWER_OFF);
            }
            file.write(buffer, 0, bufferPos);
            pos = getBlock();
            for (int i = 0; i < unwritten.size(); i++) {
                Record r = (Record) unwritten.get(i);
                r.setLogWritten(id, pos);
            }
            unwritten.clear();
            bufferPos = 0;
            long min = (long) pos * BLOCK_SIZE;
            min = MathUtils.scaleUp50Percent(Constants.FILE_MIN_SIZE, min, Constants.FILE_PAGE_SIZE, Constants.FILE_MAX_INCREMENT);
            if (min > file.length()) {
                file.setLength(min);
            }
        }
    }

    void close(boolean delete) throws SQLException {
        SQLException closeException = null;
        try {
            flush();
        } catch (SQLException e) {
            closeException = e;
        }
        // continue with close even if flush was not possible (file storage problem)
        if (file != null) {
            try {
                file.close();
                file = null;
                if (delete) {
                    database.deleteLogFileLater(fileName);
                }
            } catch (IOException e) {
                if (closeException == null) {
                    closeException = Message.convertIOException(e, fileName);
                }
            }
            file = null;
            fileNamePrefix = null;
        }
        if (closeException != null) {
            throw closeException;
        }
    }

    void addSummary(boolean dataFile, byte[] summary) throws SQLException {
        DataPage buff = DataPage.create(database, 256);
        buff.writeInt(0);
        buff.writeByte((byte) 'S');
        buff.writeInt(0);
        buff.writeInt(0); // storageId
        buff.writeInt(0); // recordId
        buff.writeInt(0); // blockCount
        buff.writeByte((byte) (dataFile ? 'D' : 'I'));
        if (summary == null) {
            buff.writeInt(0);
        } else {
            buff.checkCapacity(summary.length);
            buff.writeInt(summary.length);
            buff.write(summary, 0, summary.length);
        }
        writeBuffer(buff, null);
    }

    void addTruncate(Session session, int storageId, int recordId, int blockCount) throws SQLException {
        DataPage buff = rowBuff;
        buff.reset();
        buff.writeInt(0);
        buff.writeByte((byte) 'T');
        buff.writeInt(session.getId());
        buff.writeInt(storageId);
        buff.writeInt(recordId);
        buff.writeInt(blockCount);
        writeBuffer(buff, null);
    }

    void add(Session session, int storageId, Record record) throws SQLException {
        record.prepareWrite();
        DataPage buff = rowBuff;
        buff.reset();
        buff.writeInt(0);
        if (record.getDeleted()) {
            buff.writeByte((byte) 'D');
        } else {
            buff.writeByte((byte) 'I');
        }
        buff.writeInt(session.getId());
        buff.writeInt(storageId);
        buff.writeInt(record.getPos());
        int blockCount = record.getBlockCount();
        buff.writeInt(blockCount);
        buff.checkCapacity(DiskFile.BLOCK_SIZE * blockCount);
        record.write(buff);
        writeBuffer(buff, record);
    }

    void setFirstUncommittedPos(int firstUncommittedPos) throws SQLException {
        this.firstUncommittedPos = firstUncommittedPos;
        int pos = getBlock();
        writeHeader();
        go(pos);
    }

    int getFirstUncommittedPos() {
        return firstUncommittedPos;
    }

    private void writeHeader() throws SQLException {
        file.seek(FileStore.HEADER_LENGTH);
        DataPage buff = getHeader();
        file.write(buff.getBytes(), 0, buff.length());
    }

    void truncate(int pos) throws SQLException {
        go(pos);
        file.setLength((long) pos * BLOCK_SIZE);
    }

    private DataPage getHeader() {
        DataPage buff = rowBuff;
        buff.reset();
        buff.writeInt(id);
        buff.writeInt(firstUncommittedPos);
        // TODO need to update & use firstUnwrittenPos
        buff.writeInt(firstUnwrittenPos);
        buff.fill(3 * BLOCK_SIZE);
        return buff;
    }

    private void readHeader() throws SQLException {
        DataPage buff = getHeader();
        int len = buff.length();
        buff.reset();
        if (file.length() < FileStore.HEADER_LENGTH + len) {
            // this is an empty file
            return;
        }
        file.readFully(buff.getBytes(), 0, len);
        id = buff.readInt();
        firstUncommittedPos = buff.readInt();
        firstUnwrittenPos = buff.readInt();
    }

    int getPos() {
        return pos;
    }

    public long getFileSize() throws SQLException {
        return file.getFilePointer();
    }

    public void sync() {
        if (file != null) {
            file.sync();
        }
    }

    void updatePreparedCommit(boolean commit, int pos, int sessionId, int blocks) throws SQLException {
        synchronized (database) {
            int posNow = getBlock();
            DataPage buff = rowBuff;
            buff.reset();
            buff.writeInt(blocks);
            if (commit) {
                buff.writeByte((byte) 'C');
            } else {
                buff.writeByte((byte) 'R');
            }
            buff.writeInt(sessionId);
            buff.fill(blocks * BLOCK_SIZE);
            buff.updateChecksum();
            go(pos);
            file.write(buff.getBytes(), 0, BLOCK_SIZE * blocks);
            go(posNow);
        }
    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -