scaledrafile.java
来自「纯Java的数据库」· Java 代码 · 共 525 行 · 第 1/2 页
JAVA
525 行
/* 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.EOFException;import java.io.FileNotFoundException;import java.io.IOException;import java.io.RandomAccessFile;import java.lang.reflect.Constructor;import org.hsqldb.Database;import org.hsqldb.Trace;import org.hsqldb.lib.HsqlByteArrayInputStream;import org.hsqldb.lib.SimpleLog;import org.hsqldb.lib.Storage;// fredt@users 20030111 - patch 1.7.2 by bohgammer@users - pad file before seek() beyond end// some incompatible JVM implementations do not allow seek beyond the existing end of file/** * This class is a wapper for a random access file such as that used for * CACHED table storage. * * @author fredt@users * @version 1.8.0 * @since 1.7.2 */class ScaledRAFile implements ScaledRAInterface { static final int DATA_FILE_RAF = 0; static final int DATA_FILE_NIO = 1; static final int DATA_FILE_JAR = 2; static final long MAX_NIO_LENGTH = (1L << 28); // final SimpleLog appLog; final RandomAccessFile file; private final boolean readOnly; final String fileName; boolean isNio; boolean bufferDirty = true; final byte[] buffer; final HsqlByteArrayInputStream ba; long bufferOffset; // long seekPosition; long realPosition; static int cacheHit; /** * seekPosition is the position in seek() calls or after reading or writing * realPosition is the file position */ static Storage newScaledRAFile(Database database, String name, boolean readonly, int type, String classname, String key) throws FileNotFoundException, IOException {//#ifdef JAVA4 if (classname != null) { try { Class storageClass = null; try { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); storageClass = classLoader.loadClass(classname); } catch (ClassNotFoundException e) { storageClass = Class.forName(classname); } Constructor constructor = storageClass.getConstructor(new Class[] { String.class, Boolean.class, Object.class }); return (Storage) constructor.newInstance(new Object[] { name, new Boolean(readonly), key }); } catch (Exception e) { throw new IOException( Trace.getMessage( Trace.INVALID_STORAGE_CLASS, true, new Object[]{ e.toString() })); } }//#endif if (type == DATA_FILE_JAR) { return new ScaledRAFileInJar(name); } else if (type == DATA_FILE_RAF) { return new ScaledRAFile(database, name, readonly); } else { RandomAccessFile file = new RandomAccessFile(name, readonly ? "r" : "rw"); if (file.length() > MAX_NIO_LENGTH) { return new ScaledRAFile(database, name, file, readonly); } else { file.close(); } try { Class.forName("java.nio.MappedByteBuffer"); Class c = Class.forName("org.hsqldb.persist.ScaledRAFileHybrid"); Constructor constructor = c.getConstructor(new Class[] { Database.class, String.class, boolean.class }); return (ScaledRAInterface) constructor.newInstance( new Object[] { database, name, new Boolean(readonly) }); } catch (Exception e) { return new ScaledRAFile(database, name, readonly); } } } ScaledRAFile(Database database, String name, RandomAccessFile file, boolean readonly) throws FileNotFoundException, IOException { this.appLog = database.logger.appLog; this.readOnly = readonly; this.fileName = name; this.file = file; int bufferScale = database.getProperties().getIntegerProperty( HsqlDatabaseProperties.hsqldb_raf_buffer_scale, 12, 8, 13); int bufferSize = 1 << bufferScale; buffer = new byte[bufferSize]; ba = new HsqlByteArrayInputStream(buffer); } ScaledRAFile(Database database, String name, boolean readonly) throws FileNotFoundException, IOException { this.appLog = database.logger.appLog; this.readOnly = readonly; this.fileName = name; this.file = new RandomAccessFile(name, readonly ? "r" : "rw"); int bufferScale = database.getProperties().getIntegerProperty( HsqlDatabaseProperties.hsqldb_raf_buffer_scale, 12); int bufferSize = 1 << bufferScale; buffer = new byte[bufferSize]; ba = new HsqlByteArrayInputStream(buffer); } public long length() throws IOException { return file.length(); } /** * Some JVM's do not allow seek beyond end of file, so zeros are written * first in that case. Reported by bohgammer@users in Open Disucssion * Forum. */ public void seek(long position) throws IOException { if (!readOnly && file.length() < position) { long tempSize = position - file.length(); if (tempSize > 1 << 18) { tempSize = 1 << 18; } byte[] temp = new byte[(int) tempSize]; try { long pos = file.length(); for (; pos < position - tempSize; pos += tempSize) { file.seek(pos); file.write(temp, 0, (int) tempSize); } file.seek(pos); file.write(temp, 0, (int) (position - pos)); realPosition = position; } catch (IOException e) { appLog.logContext(e, null); throw e; } } seekPosition = position; } public long getFilePointer() throws IOException { return seekPosition; } private void readIntoBuffer() throws IOException { long filePos = seekPosition; long subOffset = filePos % buffer.length; long fileLength = file.length(); long readLength = fileLength - (filePos - subOffset); try { if (readLength <= 0) { throw new IOException("read beyond end of file"); } if (readLength > buffer.length) { readLength = buffer.length; } file.seek(filePos - subOffset); file.readFully(buffer, 0, (int) readLength); bufferOffset = filePos - subOffset; realPosition = bufferOffset + readLength; bufferDirty = false; } catch (IOException e) { resetPointer(); appLog.logContext(e, "" + realPosition + " " + readLength); throw e; } } public int read() throws IOException {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?