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

--no commit message

--no commit message
上级 4c77fc1a
......@@ -22,8 +22,8 @@ Change Log
</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.
</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.
Example: jdbc:h2:nio:~/test. So far it looks like NIO storage is faster Mac OS
memory mapped files. To use it, use the file name prefix nio: or nioMapped:
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!
</li><li>The functions BITOR, BITAND, BITXOR, and MOD now accept
and return BIGINT instead of INT.
......
......@@ -323,7 +323,7 @@ public class SysProperties {
/**
* 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
*/
public static final boolean NIO_CLEANER_HACK = getBooleanSetting("h2.nioCleanerHack", true);
......
......@@ -22,8 +22,8 @@ public class FileObjectDiskChannel implements FileObject {
FileObjectDiskChannel(String fileName, String mode) throws FileNotFoundException {
this.name = fileName;
RandomAccessFile raf = new RandomAccessFile(fileName, mode);
channel = raf.getChannel();
RandomAccessFile file = new RandomAccessFile(fileName, mode);
channel = file.getChannel();
}
public void close() throws IOException {
......@@ -46,10 +46,10 @@ public class FileObjectDiskChannel implements FileObject {
if (len == 0) {
return;
}
if (channel.size() <= off + len) {
// TODO get size can degrade performance
throw new java.io.EOFException();
}
// reading the size can reduce the performance
// if (channel.size() <= off + len) {
// throw new java.io.EOFException();
// }
ByteBuffer buf = ByteBuffer.wrap(b);
buf.position(off);
buf.limit(off + len);
......@@ -57,13 +57,10 @@ public class FileObjectDiskChannel implements FileObject {
}
public void seek(long pos) throws IOException {
// System.out.println("seek");
channel.position(pos);
}
public void setFileLength(long newLength) throws IOException {
// System.out.println("setFileLength");
// System.out.println(" "+channel.size()+" - "+channel.position());
if (newLength <= channel.size()) {
long oldPos = channel.position();
channel.truncate(newLength);
......@@ -72,20 +69,17 @@ public class FileObjectDiskChannel implements FileObject {
}
channel.position(oldPos);
} else {
// extend by writting to new location
// extend by writing to the new location
ByteBuffer b = ByteBuffer.allocate(1);
channel.write(b, newLength - 1);
}
// System.out.println(" "+channel.size()+" - "+channel.position());
}
public void sync() throws IOException {
// System.out.println("sync");
channel.force(true);
}
public void write(byte[] b, int off, int len) throws IOException {
// System.out.println("write");
ByteBuffer buf = ByteBuffer.wrap(b);
buf.position(off);
buf.limit(off + len);
......
......@@ -18,10 +18,9 @@ import org.h2.util.FileUtils;
/**
* 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 {
// TODO support files over 2 GB by using multiple buffers
private static final long GC_TIMEOUT_MS = 10000;
private final String name;
private final MapMode mode;
......@@ -36,10 +35,10 @@ public class FileObjectDiskMapped implements FileObject {
}
this.name = fileName;
file = new RandomAccessFile(fileName, mode);
remap();
reMap();
}
private void unmap() {
private void unMap() {
if (mapped != null) {
// first write all data
mapped.force();
......@@ -79,12 +78,10 @@ public class FileObjectDiskMapped implements FileObject {
}
/**
* remap byte buffer into memory, called when file size has changed or file
* was created
*
* @throws IOException
* Re-map byte buffer into memory, called when file size has changed or file
* was created.
*/
private void remap() throws IOException {
private void reMap() throws IOException {
if (file.length() > Integer.MAX_VALUE) {
throw new RuntimeException("File over 2GB is not supported yet");
}
......@@ -92,7 +89,7 @@ public class FileObjectDiskMapped implements FileObject {
if (mapped != null) {
oldPos = mapped.position();
mapped.force();
unmap();
unMap();
}
// maps new MappedByteBuffer, old one is disposed during GC
......@@ -104,8 +101,7 @@ public class FileObjectDiskMapped implements FileObject {
}
public void close() throws IOException {
unmap();
unMap();
file.close();
file = null;
}
......@@ -132,7 +128,7 @@ public class FileObjectDiskMapped implements FileObject {
public void setFileLength(long newLength) throws IOException {
FileUtils.setLength(file, newLength);
remap();
reMap();
}
public void sync() throws IOException {
......
......@@ -47,6 +47,13 @@ public class FileSystemDisk extends FileSystem {
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) {
if (fileName != null && fileName.startsWith("~")) {
String userDir = SysProperties.USER_HOME;
......@@ -82,6 +89,13 @@ public class FileSystemDisk extends FileSystem {
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) {
if (SysProperties.TRACE_IO) {
System.out.println("FileSystem." + method + " " + fileName + " " + o);
......@@ -350,6 +364,10 @@ public class FileSystemDisk extends FileSystem {
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() {
trace("freeMemoryAndFinalize", null, null);
Runtime rt = Runtime.getRuntime();
......
......@@ -25,12 +25,12 @@ public class FileSystemDiskNio extends FileSystemDisk {
public String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir)
throws IOException {
String file = super.createTempFile(name, suffix, deleteOnExit, inTempDir);
return FileSystem.PREFIX_NIO + file;
return getPrefix() + file;
}
protected String translateFileName(String fileName) {
if (fileName.startsWith(FileSystem.PREFIX_NIO)) {
fileName = fileName.substring(FileSystem.PREFIX_NIO.length());
if (fileName.startsWith(getPrefix())) {
fileName = fileName.substring(getPrefix().length());
}
return super.translateFileName(fileName);
}
......@@ -40,23 +40,23 @@ public class FileSystemDiskNio extends FileSystemDisk {
}
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 {
String[] list = super.listFiles(path);
for (int i = 0; list != null && i < list.length; i++) {
list[i] = FileSystem.PREFIX_NIO + list[i];
list[i] = getPrefix() + list[i];
}
return list;
}
public String getParent(String fileName) {
return FileSystem.PREFIX_NIO + super.getParent(fileName);
return getPrefix() + super.getParent(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 {
......@@ -77,6 +77,23 @@ public class FileSystemDiskNio extends FileSystemDisk {
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 {
return new FileObjectDiskChannel(fileName, mode);
}
......
......@@ -12,7 +12,7 @@ import java.io.IOException;
* This file system stores files on disk and uses java.nio to access the files.
* This class used memory mapped files.
*/
public class FileSystemDiskNioMapped extends FileSystemDisk {
public class FileSystemDiskNioMapped extends FileSystemDiskNio {
private static final FileSystemDiskNioMapped INSTANCE = new FileSystemDiskNioMapped();
......@@ -20,6 +20,10 @@ public class FileSystemDiskNioMapped extends FileSystemDisk {
return INSTANCE;
}
protected String getPrefix() {
return FileSystem.PREFIX_NIO_MAPPED;
}
protected FileObject open(String fileName, String mode) throws IOException {
return new FileObjectDiskMapped(fileName, mode);
}
......
......@@ -523,6 +523,12 @@ public class TableLink extends Table {
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) {
prepared.put(sql, prep);
}
......
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
#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
......
......@@ -582,4 +582,5 @@ bot jot delicious rife appenders circles spelling cash sky ecm nuxeo poland
opengeospatial sfs symmetric obsolete failing parenthesis unloading refreshed
grails reloading slightly accepting deploying conflicting recovered counters
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论