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

📄 cache.java

📁 一个用java写的开源的数据库系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* Copyrights and Licenses * * This product includes Hypersonic SQL. * Originally developed by Thomas Mueller and the Hypersonic SQL Group.  * * Copyright (c) 1995-2000 by the Hypersonic SQL 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.  *     -  All advertising materials mentioning features or use of this software must display the *        following acknowledgment: "This product includes Hypersonic SQL."  *     -  Products derived from this software may not be called "Hypersonic SQL" nor may *        "Hypersonic SQL" appear in their names without prior written permission of the *         Hypersonic SQL Group.  *     -  Redistributions of any form whatsoever must retain the following acknowledgment: "This *          product includes Hypersonic SQL."  * This software is provided "as is" and any expressed 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 the Hypersonic SQL Group or its 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 any 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.  * This software consists of voluntary contributions made by many individuals on behalf of the * Hypersonic SQL Group. * * * For work added by the HSQL Development Group: * * Copyright (c) 2001-2002, 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, including earlier * license statements (above) and comply with all above license conditions. * * 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, including earlier * license statements (above) and comply with all above license conditions. * * 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;import java.io.IOException;import java.io.File;import java.sql.SQLException;// fredt@users 20011220 - patch 437174 by hjb@users - cache update// most changes and comments by HSB are kept unchanged// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP) - cache update// fredt@users 20020320 - doc 1.7.0 by boucherb@users - doc update/** * * Handles cached tables through a .data file and memory cache. * * @version    1.7.1 * @see        Row * @see        CacheFree */class Cache {    private HsqlDatabaseProperties props;    private boolean                newCacheType;    private final int              cacheLength;    private final int              writerLength;    private final int              maxCacheSize;    private final int              multiplierMask;    private CachedRow              rData[];    private CachedRow              rWriter[];    private CachedRow              rFirst;             // must point to one of rData[]    private CachedRow              rLastChecked;       // can be any row    // sqlbob@users - changed visibility for children.    protected String         sName;    protected int            iFreePos;    protected DatabaseFile   rFile;    private static final int FREE_POS_POS     = 16;    // where iFreePos is saved    private static final int INITIAL_FREE_POS = 32;    private static final int MAX_FREE_COUNT   = 1024;    private CacheFree        fRoot;    private int              iFreeCount;    private int              iCacheSize;    /**     *  Construct a new Cache object with the given database path name and     *  the properties object to get the initial settings from.     */    Cache(String name, HsqlDatabaseProperties props) {        this.props = props;        int cacheScale = 0;        try {            cacheScale = props.getIntegerProperty("hsqldb.cache_scale", 0);        } catch (NumberFormatException e) {            Trace.printSystemOut(                "bad value for hsqldb.cache_scale in properties file");        }        if (cacheScale == 0) {            // HJB-2001-06-21: use larger cache size            cacheScale = 15;        } else if (cacheScale < 8) {            cacheScale = 8;        } else if (cacheScale > 16) {            cacheScale = 16;        }        cacheLength = 1 << cacheScale;        // HJB-2001-06-21: use different smaller size for the writer        writerLength = cacheLength - 3;        // HJB-2001-06-21: let the cache be larger than the array        maxCacheSize   = cacheLength * 3;        multiplierMask = cacheLength - 1;        sName          = name;        rData          = new CachedRow[cacheLength];        rWriter        = new CachedRow[writerLength];    // HJB-2001-06-21    }    /**     * Opens this object's database file.     */    void open(boolean readonly) throws SQLException {        try {            boolean exists = false;            File    f      = new File(sName);            if (f.exists() && f.length() > FREE_POS_POS) {                exists = true;            }            rFile = new DatabaseFile(sName, readonly ? "r"                                                     : "rw", 2048);            if (exists) {                rFile.readSeek(FREE_POS_POS);                iFreePos = rFile.readInteger();            } else {                iFreePos = INITIAL_FREE_POS;                props.setProperty("hsqldb.cache_version", "1.7.0");            }            String cacheVersion = props.getProperty("hsqldb.cache_version",                "1.6.0");            if (cacheVersion.equals("1.7.0")) {                newCacheType = true;            }        } catch (Exception e) {            throw Trace.error(Trace.FILE_IO_ERROR,                              "error " + e + " opening " + sName);        }    }    /**     *  Writes out all cached data and the free position to this     *  object's database file and then closes the file.     */    void flush() throws SQLException {        if (rFile == null) {            return;        }        try {            rFile.seek(FREE_POS_POS);            rFile.writeInteger(iFreePos);            saveAll();            boolean empty = (rFile.length() < INITIAL_FREE_POS);            rFile.close();            rFile = null;            if (empty) {                new File(sName).delete();            }        } catch (Exception e) {            throw Trace.error(Trace.FILE_IO_ERROR,                              "error " + e + " closing " + sName);        }    }    /**     *  Closes this object's database file without flushing pending writes.     */    void closeFile() throws SQLException {        if (rFile == null) {            return;        }        try {            rFile.close();            rFile = null;        } catch (Exception e) {            throw Trace.error(Trace.FILE_IO_ERROR,                              "error " + e + " in shutdown " + sName);        }    }    /**     * Marks space in this object's cache file as free. <p>     *     * <B>Note:</B> If there exists more than MAX_FREE_COUNT free positions,     * then they are probably all too small, so we start a new list. <p>     *     *  todo: This is wrong when deleting lots of records     */    void free(CachedRow r) throws SQLException {        iFreeCount++;        CacheFree n = new CacheFree();        n.iPos    = r.iPos;        n.iLength = r.storageSize;        if (iFreeCount > MAX_FREE_COUNT) {            iFreeCount = 0;        } else {            n.fNext = fRoot;        }        fRoot = n;        // it's possible to remove roots too        remove(r);    }    /**     * Calculates the number of bytes required to store a Row in this object's     * database file.     */    protected void setStorageSize(CachedRow r) throws SQLException {        // 32 bytes overhead for each index + iSize, iPos        Table t    = r.getTable();        int   size = 8 + 32 * t.getIndexCount();        if (newCacheType) {            size += BinaryServerRowOutput.getSize(r);        } else {            size += BinaryDatabaseRowOutput.getSize(r);        }        size          = ((size + 7) / 8) * 8;    // align to 8 byte blocks        r.storageSize = size;    }    /**     * Adds a Row to the Cache. <p>     *     * A Row is added by walking the list of CacheFree     * objects to see if there is available space to store it,     * reusing space if it exists.  Otherwise , this object's cache     * file is grown to accomadate it.     */    void add(CachedRow r) throws SQLException {        setStorageSize(r);        int       rowSize = r.storageSize;        int       size    = rowSize;        CacheFree f       = fRoot;        CacheFree last    = null;        int       i       = iFreePos;        while (f != null) {            if (Trace.TRACE) {                Trace.stop();            }            // first that is long enough            if (f.iLength >= size) {                i    = f.iPos;                size = f.iLength - size;                if (size < 8) {                    // remove almost empty blocks                    if (last == null) {                        fRoot = f.fNext;                    } else {                        last.fNext = f.fNext;                    }                    iFreeCount--;                } else {                    f.iLength = size;                    f.iPos    += rowSize;                }                break;            }            last = f;            f    = f.fNext;        }        r.setPos(i);        if (i == iFreePos) {            iFreePos += size;        }        // HJB-2001-06-21        int       k      = (i >> 3) & multiplierMask;        CachedRow before = rData[k];        if (before == null) {            before = rFirst;        }        r.insert(before);        iCacheSize++;        rData[k] = r;        rFirst   = r;    }    /**     * Constructs a new Row for the specified table, using row data read     * at the specified position (pos) in this object's database file.     */    protected CachedRow makeRow(int pos, Table t) throws SQLException {        CachedRow r = null;        try {            rFile.readSeek(pos);            int  size     = rFile.readInteger();            byte buffer[] = new byte[size];            rFile.read(buffer);            DatabaseRowInputInterface in;            if (newCacheType) {                in = new BinaryServerRowInput(buffer, pos);            } else {                in = new BinaryDatabaseRowInput(buffer, pos);            }            r = new CachedRow(t, in);

⌨️ 快捷键说明

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