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

📄 datafilecache.java

📁 纯Java的数据库
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* Copyright (c) 2001-2008, The HSQL Development Group * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the HSQL Development Group nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */package org.hsqldb.persist;import java.io.File;import java.io.IOException;import org.hsqldb.Database;import org.hsqldb.HsqlException;import org.hsqldb.Trace;import org.hsqldb.lib.FileAccess;import org.hsqldb.lib.FileUtil;import org.hsqldb.lib.SimpleLog;import org.hsqldb.lib.StopWatch;import org.hsqldb.lib.Storage;import org.hsqldb.lib.ZipUnzipFile;import org.hsqldb.rowio.RowInputBinary;import org.hsqldb.rowio.RowInputInterface;import org.hsqldb.rowio.RowOutputBinary;import org.hsqldb.rowio.RowOutputInterface;import org.hsqldb.store.BitMap;/** * Acts as a manager for CACHED table persistence.<p> * * This contains the top level functionality. Provides file management services * and access.<p> * * Rewritten for 1.8.0 together with Cache. * * @author fredt@users * @version 1.8.0 * @since 1.7.2 */public class DataFileCache {    protected FileAccess fa;    // flags    public static final int FLAG_ISSAVED = 2;    public static final int FLAG_ROWINFO = 3;    // file format fields    static final int LONG_EMPTY_SIZE      = 4;     // empty space size    static final int LONG_FREE_POS_POS    = 12;    // where iFreePos is saved    static final int LONG_EMPTY_INDEX_POS = 20;    // empty space index    static final int FLAGS_POS            = 28;    static final int INITIAL_FREE_POS     = 32;    //    DataFileBlockManager     freeBlocks;    private static final int initIOBufferSize = 256;    //    protected String   fileName;    protected String   backupFileName;    protected Database database;    // this flag is used externally to determine if a backup is required    protected boolean fileModified;    protected int     cacheFileScale;    // post openning constant fields    protected boolean cacheReadonly;    // cache operation mode    protected boolean storeOnInsert;    //    protected int     cachedRowPadding = 8;    protected boolean hasRowInfo       = false;    // reusable input / output streams    protected RowInputInterface  rowIn;    protected RowOutputInterface rowOut;    //    public long maxDataFileSize;    //    protected Storage dataFile;    protected long    fileFreePosition;    protected int     maxCacheSize;                // number of Rows    protected long    maxCacheBytes;               // number of bytes    protected int     maxFreeBlocks;    protected Cache   cache;    public DataFileCache(Database db,                         String baseFileName) throws HsqlException {        initParams(db, baseFileName);        cache = new Cache(this);    }    /**     * initial external parameters are set here.     */    protected void initParams(Database database,                              String baseFileName) throws HsqlException {        HsqlDatabaseProperties props = database.getProperties();        fileName       = baseFileName + ".data";        backupFileName = baseFileName + ".backup";        this.database  = database;        fa             = database.getFileAccess();        int cacheScale =            props.getIntegerProperty(HsqlDatabaseProperties.hsqldb_cache_scale,                                     14, 8, 18);        int cacheSizeScale = props.getIntegerProperty(            HsqlDatabaseProperties.hsqldb_cache_size_scale, 10, 6, 20);        int cacheFreeCountScale = props.getIntegerProperty(            HsqlDatabaseProperties.hsqldb_cache_free_count_scale, 9, 6, 12);        cacheFileScale = database.getProperties().getIntegerProperty(            HsqlDatabaseProperties.hsqldb_cache_file_scale, 1);        if (cacheFileScale != 1) {            cacheFileScale = 8;        }        cacheReadonly = database.isFilesReadOnly();        int lookupTableLength = 1 << cacheScale;        int avgRowBytes       = 1 << cacheSizeScale;        maxCacheSize    = lookupTableLength * 3;        maxCacheBytes   = maxCacheSize * avgRowBytes;        maxDataFileSize = cacheFileScale == 1 ? Integer.MAX_VALUE                                              : (long) Integer.MAX_VALUE * 4;        maxFreeBlocks   = 1 << cacheFreeCountScale;        dataFile        = null;    }    /**     * Opens the *.data file for this cache, setting the variables that     * allow access to the particular database version of the *.data file.     */    public void open(boolean readonly) throws HsqlException {        fileFreePosition = 0;        database.logger.appLog.logContext(SimpleLog.LOG_NORMAL, "start");        try {            boolean preexists = database.isFilesInJar();            long    freesize  = 0;            if (!preexists && fa.isStreamElement(fileName)) {                // OOo related code                if (database.isStoredFileAccess()) {                    preexists = true;                }                // OOo end;                if (!preexists) {                    // discard "empty" databases                    File f = new File(fileName);                    preexists = f.length() > INITIAL_FREE_POS;                }            }            if (preexists) {                String version = database.getProperties().getProperty(                    HsqlDatabaseProperties.hsqldb_cache_version);                boolean v17 =                    HsqlDatabaseProperties.VERSION_STRING_1_7_0.equals(                        version);                // for later versions                boolean v18 =                    HsqlDatabaseProperties.VERSION_STRING_1_8_0.equals(                        version);                if (!v17) {                    throw Trace.error(Trace.WRONG_DATABASE_FILE_VERSION);                }            }            boolean isNio = database.getProperties().isPropertyTrue(                HsqlDatabaseProperties.hsqldb_nio_data_file);            int fileType = isNio ? ScaledRAFile.DATA_FILE_NIO                                 : ScaledRAFile.DATA_FILE_RAF;            if (database.isFilesInJar()) {                fileType = ScaledRAFile.DATA_FILE_JAR;            }            // oj@openofice.org - change to file access api            String cname =                database.getURLProperties().getProperty("storage_class_name");            String skey =                database.getURLProperties().getProperty("storage_key");            dataFile = ScaledRAFile.newScaledRAFile(database, fileName,                    readonly, fileType, cname, skey);            if (preexists) {                dataFile.seek(FLAGS_POS);                int flags = dataFile.readInt();                hasRowInfo = BitMap.isSet(flags, FLAG_ROWINFO);                dataFile.seek(LONG_EMPTY_SIZE);                freesize = dataFile.readLong();                dataFile.seek(LONG_FREE_POS_POS);                fileFreePosition = dataFile.readLong();                if (fileFreePosition < INITIAL_FREE_POS) {                    fileFreePosition = INITIAL_FREE_POS;                }            } else {                fileFreePosition = INITIAL_FREE_POS;                dataFile.seek(LONG_FREE_POS_POS);                dataFile.writeLong(INITIAL_FREE_POS);                // set unsaved flag;                dataFile.seek(FLAGS_POS);                dataFile.writeInt(0);            }            initBuffers();            fileModified = false;            freeBlocks = new DataFileBlockManager(maxFreeBlocks,                                                  cacheFileScale, freesize);            database.logger.appLog.logContext(SimpleLog.LOG_NORMAL, "end");        } catch (Throwable e) {            database.logger.appLog.logContext(e, "failed");            close(false);            throw Trace.error(Trace.FILE_IO_ERROR, Trace.DataFileCache_open,                              new Object[] {                e, fileName            });        }    }    /**     *  Parameter write indicates either an orderly close, or a fast close     *  without backup.     *     *  When false, just closes the file.     *     *  When true, writes out all cached rows that have been modified and the     *  free position pointer for the *.data file and then closes the file.     */    public void close(boolean write) throws HsqlException {        SimpleLog appLog = database.logger.appLog;        try {            if (cacheReadonly) {                if (dataFile != null) {                    dataFile.close();                }                return;            }            StopWatch sw = new StopWatch();            appLog.sendLine(SimpleLog.LOG_NORMAL,                            "DataFileCache.close(" + write + ") : start");            if (write) {                cache.saveAll();                Trace.printSystemOut("saveAll: " + sw.elapsedTime());                appLog.sendLine(SimpleLog.LOG_NORMAL,                                "DataFileCache.close() : save data");                if (fileModified || freeBlocks.isModified()) {                    // set empty                    dataFile.seek(LONG_EMPTY_SIZE);                    dataFile.writeLong(freeBlocks.getLostBlocksSize());                    // set end                    dataFile.seek(LONG_FREE_POS_POS);                    dataFile.writeLong(fileFreePosition);                    // set saved flag;                    dataFile.seek(FLAGS_POS);                    int flag = BitMap.set(0, FLAG_ISSAVED);                    if (hasRowInfo) {                        flag = BitMap.set(flag, FLAG_ROWINFO);                    }                    dataFile.writeInt(flag);                    appLog.sendLine(SimpleLog.LOG_NORMAL,                                    "DataFileCache.close() : flags");                    //                    if (dataFile.length() != fileFreePosition) {                        dataFile.seek(fileFreePosition);                    }                    appLog.sendLine(SimpleLog.LOG_NORMAL,                                    "DataFileCache.close() : seek end");                    Trace.printSystemOut("pos and flags: " + sw.elapsedTime());                }            }            if (dataFile != null) {                dataFile.close();                appLog.sendLine(SimpleLog.LOG_NORMAL,                                "DataFileCache.close() : close");                dataFile = null;                Trace.printSystemOut("close: " + sw.elapsedTime());            }            boolean empty = fileFreePosition == INITIAL_FREE_POS;            if (empty) {                fa.removeElement(fileName);                fa.removeElement(backupFileName);            }        } catch (Throwable e) {            appLog.logContext(e, null);            throw Trace.error(Trace.FILE_IO_ERROR, Trace.DataFileCache_close,                              new Object[] {                e, fileName            });        }    }    protected void initBuffers() {        if (rowOut == null                || ((RowOutputBinary) rowOut).getBuffer().length                   > initIOBufferSize) {            rowOut = new RowOutputBinary(256);        }        if (rowIn == null                || ((RowInputBinary) rowIn).getBuffer().length                   > initIOBufferSize) {            rowIn = new RowInputBinary(new byte[256]);        }    }    /**     *  Writes out all the rows to a new file without fragmentation.     */    public void defrag() throws HsqlException {        if (cacheReadonly) {            return;        }        if (fileFreePosition == INITIAL_FREE_POS) {            return;        }        database.logger.appLog.logContext(SimpleLog.LOG_NORMAL, "start");        try {            boolean wasNio = dataFile.wasNio();            cache.saveAll();            DataFileDefrag dfd = new DataFileDefrag(database, this, fileName);            dfd.process();            close(false);

⌨️ 快捷键说明

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