提交 2ae49669 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 4c77fc1a
...@@ -22,8 +22,8 @@ Change Log ...@@ -22,8 +22,8 @@ Change Log
</li><li>When converting CLOB to BINARY, each character resulted in one byte. </li><li>When converting CLOB to BINARY, each character resulted in one byte.
Now, the text is parsed as a hex as when converting VARCHAR. Now, the text is parsed as a hex as when converting VARCHAR.
</li><li>New experimental NIO storage mechanism with both FileChannel and </li><li>New experimental NIO storage mechanism with both FileChannel and
memory mapped files. To use it, prepend nio: or nioMapped: to the file name. memory mapped files. To use it, use the file name prefix nio: or nioMapped:
Example: jdbc:h2:nio:~/test. So far it looks like NIO storage is faster Mac OS as in jdbc:h2:nio:~/test. So far it looks like NIO storage is faster Mac OS
but slower on some Windows systems. Thanks a lot to Jan Kotek for the patch! but slower on some Windows systems. Thanks a lot to Jan Kotek for the patch!
</li><li>The functions BITOR, BITAND, BITXOR, and MOD now accept </li><li>The functions BITOR, BITAND, BITXOR, and MOD now accept
and return BIGINT instead of INT. and return BIGINT instead of INT.
......
...@@ -323,7 +323,7 @@ public class SysProperties { ...@@ -323,7 +323,7 @@ public class SysProperties {
/** /**
* System property <code>h2.nioCleanerHack</code> (default: true).<br /> * System property <code>h2.nioCleanerHack</code> (default: true).<br />
* If possible, use a hack to unmap the mapped file. See also * If possible, use a hack to un-map the mapped file. See also
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4724038 * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4724038
*/ */
public static final boolean NIO_CLEANER_HACK = getBooleanSetting("h2.nioCleanerHack", true); public static final boolean NIO_CLEANER_HACK = getBooleanSetting("h2.nioCleanerHack", true);
......
...@@ -22,8 +22,8 @@ public class FileObjectDiskChannel implements FileObject { ...@@ -22,8 +22,8 @@ public class FileObjectDiskChannel implements FileObject {
FileObjectDiskChannel(String fileName, String mode) throws FileNotFoundException { FileObjectDiskChannel(String fileName, String mode) throws FileNotFoundException {
this.name = fileName; this.name = fileName;
RandomAccessFile raf = new RandomAccessFile(fileName, mode); RandomAccessFile file = new RandomAccessFile(fileName, mode);
channel = raf.getChannel(); channel = file.getChannel();
} }
public void close() throws IOException { public void close() throws IOException {
...@@ -46,10 +46,10 @@ public class FileObjectDiskChannel implements FileObject { ...@@ -46,10 +46,10 @@ public class FileObjectDiskChannel implements FileObject {
if (len == 0) { if (len == 0) {
return; return;
} }
if (channel.size() <= off + len) { // reading the size can reduce the performance
// TODO get size can degrade performance // if (channel.size() <= off + len) {
throw new java.io.EOFException(); // throw new java.io.EOFException();
} // }
ByteBuffer buf = ByteBuffer.wrap(b); ByteBuffer buf = ByteBuffer.wrap(b);
buf.position(off); buf.position(off);
buf.limit(off + len); buf.limit(off + len);
...@@ -57,13 +57,10 @@ public class FileObjectDiskChannel implements FileObject { ...@@ -57,13 +57,10 @@ public class FileObjectDiskChannel implements FileObject {
} }
public void seek(long pos) throws IOException { public void seek(long pos) throws IOException {
// System.out.println("seek");
channel.position(pos); channel.position(pos);
} }
public void setFileLength(long newLength) throws IOException { public void setFileLength(long newLength) throws IOException {
// System.out.println("setFileLength");
// System.out.println(" "+channel.size()+" - "+channel.position());
if (newLength <= channel.size()) { if (newLength <= channel.size()) {
long oldPos = channel.position(); long oldPos = channel.position();
channel.truncate(newLength); channel.truncate(newLength);
...@@ -72,20 +69,17 @@ public class FileObjectDiskChannel implements FileObject { ...@@ -72,20 +69,17 @@ public class FileObjectDiskChannel implements FileObject {
} }
channel.position(oldPos); channel.position(oldPos);
} else { } else {
// extend by writting to new location // extend by writing to the new location
ByteBuffer b = ByteBuffer.allocate(1); ByteBuffer b = ByteBuffer.allocate(1);
channel.write(b, newLength - 1); channel.write(b, newLength - 1);
} }
// System.out.println(" "+channel.size()+" - "+channel.position());
} }
public void sync() throws IOException { public void sync() throws IOException {
// System.out.println("sync");
channel.force(true); channel.force(true);
} }
public void write(byte[] b, int off, int len) throws IOException { public void write(byte[] b, int off, int len) throws IOException {
// System.out.println("write");
ByteBuffer buf = ByteBuffer.wrap(b); ByteBuffer buf = ByteBuffer.wrap(b);
buf.position(off); buf.position(off);
buf.limit(off + len); buf.limit(off + len);
......
...@@ -18,10 +18,9 @@ import org.h2.util.FileUtils; ...@@ -18,10 +18,9 @@ import org.h2.util.FileUtils;
/** /**
* FileObject which is using NIO MappedByteBuffer mapped to memory from file. * FileObject which is using NIO MappedByteBuffer mapped to memory from file.
*/ */
// TODO support files over 2 GB by using multiple buffers
// TODO howto dispose MappedByteBuffer?
public class FileObjectDiskMapped implements FileObject { public class FileObjectDiskMapped implements FileObject {
// TODO support files over 2 GB by using multiple buffers
private static final long GC_TIMEOUT_MS = 10000; private static final long GC_TIMEOUT_MS = 10000;
private final String name; private final String name;
private final MapMode mode; private final MapMode mode;
...@@ -36,10 +35,10 @@ public class FileObjectDiskMapped implements FileObject { ...@@ -36,10 +35,10 @@ public class FileObjectDiskMapped implements FileObject {
} }
this.name = fileName; this.name = fileName;
file = new RandomAccessFile(fileName, mode); file = new RandomAccessFile(fileName, mode);
remap(); reMap();
} }
private void unmap() { private void unMap() {
if (mapped != null) { if (mapped != null) {
// first write all data // first write all data
mapped.force(); mapped.force();
...@@ -79,12 +78,10 @@ public class FileObjectDiskMapped implements FileObject { ...@@ -79,12 +78,10 @@ public class FileObjectDiskMapped implements FileObject {
} }
/** /**
* remap byte buffer into memory, called when file size has changed or file * Re-map byte buffer into memory, called when file size has changed or file
* was created * was created.
*
* @throws IOException
*/ */
private void remap() throws IOException { private void reMap() throws IOException {
if (file.length() > Integer.MAX_VALUE) { if (file.length() > Integer.MAX_VALUE) {
throw new RuntimeException("File over 2GB is not supported yet"); throw new RuntimeException("File over 2GB is not supported yet");
} }
...@@ -92,7 +89,7 @@ public class FileObjectDiskMapped implements FileObject { ...@@ -92,7 +89,7 @@ public class FileObjectDiskMapped implements FileObject {
if (mapped != null) { if (mapped != null) {
oldPos = mapped.position(); oldPos = mapped.position();
mapped.force(); mapped.force();
unmap(); unMap();
} }
// maps new MappedByteBuffer, old one is disposed during GC // maps new MappedByteBuffer, old one is disposed during GC
...@@ -104,8 +101,7 @@ public class FileObjectDiskMapped implements FileObject { ...@@ -104,8 +101,7 @@ public class FileObjectDiskMapped implements FileObject {
} }
public void close() throws IOException { public void close() throws IOException {
unmap(); unMap();
file.close(); file.close();
file = null; file = null;
} }
...@@ -132,7 +128,7 @@ public class FileObjectDiskMapped implements FileObject { ...@@ -132,7 +128,7 @@ public class FileObjectDiskMapped implements FileObject {
public void setFileLength(long newLength) throws IOException { public void setFileLength(long newLength) throws IOException {
FileUtils.setLength(file, newLength); FileUtils.setLength(file, newLength);
remap(); reMap();
} }
public void sync() throws IOException { public void sync() throws IOException {
......
...@@ -47,6 +47,13 @@ public class FileSystemDisk extends FileSystem { ...@@ -47,6 +47,13 @@ public class FileSystemDisk extends FileSystem {
return new File(fileName).length(); return new File(fileName).length();
} }
/**
* Translate the file name to the native format.
* This will expand the home directory (~).
*
* @param fileName the file name
* @return the native file name
*/
protected String translateFileName(String fileName) { protected String translateFileName(String fileName) {
if (fileName != null && fileName.startsWith("~")) { if (fileName != null && fileName.startsWith("~")) {
String userDir = SysProperties.USER_HOME; String userDir = SysProperties.USER_HOME;
...@@ -82,6 +89,13 @@ public class FileSystemDisk extends FileSystem { ...@@ -82,6 +89,13 @@ public class FileSystemDisk extends FileSystem {
throw Message.getSQLException(ErrorCode.FILE_RENAME_FAILED_2, new String[]{oldName, newName}); throw Message.getSQLException(ErrorCode.FILE_RENAME_FAILED_2, new String[]{oldName, newName});
} }
/**
* Print a trace message if tracing is enabled.
*
* @param method the method
* @param fileName the file name
* @param o the object
*/
protected void trace(String method, String fileName, Object o) { protected void trace(String method, String fileName, Object o) {
if (SysProperties.TRACE_IO) { if (SysProperties.TRACE_IO) {
System.out.println("FileSystem." + method + " " + fileName + " " + o); System.out.println("FileSystem." + method + " " + fileName + " " + o);
...@@ -350,6 +364,10 @@ public class FileSystemDisk extends FileSystem { ...@@ -350,6 +364,10 @@ public class FileSystemDisk extends FileSystem {
return in; return in;
} }
/**
* Call the garbage collection and run finalization. This close all files that
* were not closed, and are no longer referenced.
*/
protected void freeMemoryAndFinalize() { protected void freeMemoryAndFinalize() {
trace("freeMemoryAndFinalize", null, null); trace("freeMemoryAndFinalize", null, null);
Runtime rt = Runtime.getRuntime(); Runtime rt = Runtime.getRuntime();
......
...@@ -25,12 +25,12 @@ public class FileSystemDiskNio extends FileSystemDisk { ...@@ -25,12 +25,12 @@ public class FileSystemDiskNio extends FileSystemDisk {
public String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir) public String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir)
throws IOException { throws IOException {
String file = super.createTempFile(name, suffix, deleteOnExit, inTempDir); String file = super.createTempFile(name, suffix, deleteOnExit, inTempDir);
return FileSystem.PREFIX_NIO + file; return getPrefix() + file;
} }
protected String translateFileName(String fileName) { protected String translateFileName(String fileName) {
if (fileName.startsWith(FileSystem.PREFIX_NIO)) { if (fileName.startsWith(getPrefix())) {
fileName = fileName.substring(FileSystem.PREFIX_NIO.length()); fileName = fileName.substring(getPrefix().length());
} }
return super.translateFileName(fileName); return super.translateFileName(fileName);
} }
...@@ -40,23 +40,23 @@ public class FileSystemDiskNio extends FileSystemDisk { ...@@ -40,23 +40,23 @@ public class FileSystemDiskNio extends FileSystemDisk {
} }
public String normalize(String fileName) throws SQLException { public String normalize(String fileName) throws SQLException {
return FileSystem.PREFIX_NIO + super.normalize(fileName); return getPrefix() + super.normalize(fileName);
} }
public String[] listFiles(String path) throws SQLException { public String[] listFiles(String path) throws SQLException {
String[] list = super.listFiles(path); String[] list = super.listFiles(path);
for (int i = 0; list != null && i < list.length; i++) { for (int i = 0; list != null && i < list.length; i++) {
list[i] = FileSystem.PREFIX_NIO + list[i]; list[i] = getPrefix() + list[i];
} }
return list; return list;
} }
public String getParent(String fileName) { public String getParent(String fileName) {
return FileSystem.PREFIX_NIO + super.getParent(fileName); return getPrefix() + super.getParent(fileName);
} }
public String getAbsolutePath(String fileName) { public String getAbsolutePath(String fileName) {
return FileSystem.PREFIX_NIO + super.getAbsolutePath(fileName); return getPrefix() + super.getAbsolutePath(fileName);
} }
public FileObject openFileObject(String fileName, String mode) throws IOException { public FileObject openFileObject(String fileName, String mode) throws IOException {
...@@ -77,6 +77,23 @@ public class FileSystemDiskNio extends FileSystemDisk { ...@@ -77,6 +77,23 @@ public class FileSystemDiskNio extends FileSystemDisk {
return f; return f;
} }
/**
* Get the prefix for this file system.
*
* @return the prefix
*/
protected String getPrefix() {
return FileSystem.PREFIX_NIO;
}
/**
* Try to open a file with this name and mode.
*
* @param fileName the file name
* @param mode the open mode
* @return the file object
* @throws IOException if opening fails
*/
protected FileObject open(String fileName, String mode) throws IOException { protected FileObject open(String fileName, String mode) throws IOException {
return new FileObjectDiskChannel(fileName, mode); return new FileObjectDiskChannel(fileName, mode);
} }
......
...@@ -12,7 +12,7 @@ import java.io.IOException; ...@@ -12,7 +12,7 @@ import java.io.IOException;
* This file system stores files on disk and uses java.nio to access the files. * This file system stores files on disk and uses java.nio to access the files.
* This class used memory mapped files. * This class used memory mapped files.
*/ */
public class FileSystemDiskNioMapped extends FileSystemDisk { public class FileSystemDiskNioMapped extends FileSystemDiskNio {
private static final FileSystemDiskNioMapped INSTANCE = new FileSystemDiskNioMapped(); private static final FileSystemDiskNioMapped INSTANCE = new FileSystemDiskNioMapped();
...@@ -20,6 +20,10 @@ public class FileSystemDiskNioMapped extends FileSystemDisk { ...@@ -20,6 +20,10 @@ public class FileSystemDiskNioMapped extends FileSystemDisk {
return INSTANCE; return INSTANCE;
} }
protected String getPrefix() {
return FileSystem.PREFIX_NIO_MAPPED;
}
protected FileObject open(String fileName, String mode) throws IOException { protected FileObject open(String fileName, String mode) throws IOException {
return new FileObjectDiskMapped(fileName, mode); return new FileObjectDiskMapped(fileName, mode);
} }
......
...@@ -523,6 +523,12 @@ public class TableLink extends Table { ...@@ -523,6 +523,12 @@ public class TableLink extends Table {
return ROW_COUNT_APPROXIMATION; return ROW_COUNT_APPROXIMATION;
} }
/**
* Add this prepared statement to the list of cached statements.
*
* @param prep the prepared statement
* @param sql the SQL statement
*/
public void reusePreparedStatement(PreparedStatement prep, String sql) { public void reusePreparedStatement(PreparedStatement prep, String sql) {
prepared.put(sql, prep); prepared.put(sql, prep);
} }
......
db1 = H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa db1 = H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
#db2 = H2 (nio), org.h2.Driver, jdbc:h2:nio:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
#db3 = H2 (nioMapped), org.h2.Driver, jdbc:h2:nioMapped:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
#db2 = H2 (MVCC), org.h2.Driver, jdbc:h2:data/test_mvcc;MVCC=TRUE, sa, sa #db2 = H2 (MVCC), org.h2.Driver, jdbc:h2:data/test_mvcc;MVCC=TRUE, sa, sa
#xdb2 = H2 (XTEA), org.h2.Driver, jdbc:h2:data/test_xtea;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=XTEA, sa, sa 123 #xdb2 = H2 (XTEA), org.h2.Driver, jdbc:h2:data/test_xtea;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=XTEA, sa, sa 123
#xdb3 = H2 (AES), org.h2.Driver, jdbc:h2:data/test_aes;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=AES, sa, sa 123 #xdb3 = H2 (AES), org.h2.Driver, jdbc:h2:data/test_aes;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=AES, sa, sa 123
......
...@@ -582,4 +582,5 @@ bot jot delicious rife appenders circles spelling cash sky ecm nuxeo poland ...@@ -582,4 +582,5 @@ bot jot delicious rife appenders circles spelling cash sky ecm nuxeo poland
opengeospatial sfs symmetric obsolete failing parenthesis unloading refreshed opengeospatial sfs symmetric obsolete failing parenthesis unloading refreshed
grails reloading slightly accepting deploying conflicting recovered counters grails reloading slightly accepting deploying conflicting recovered counters
versus extracts squirrel misdirected rle looking arc addressed european versus extracts squirrel misdirected rle looking arc addressed european
soerensen favicon glass restarts flexive fish soerensen favicon glass restarts flexive fish resulted vpda mvc kotek jan
consistently springfuse
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论