提交 e4a98148 authored 作者: Noel Grandin's avatar Noel Grandin

add an option to control size of compress later cache in the nioMemLZF filesystem

上级 7c1478a2
...@@ -1589,7 +1589,10 @@ The following file systems are included: ...@@ -1589,7 +1589,10 @@ The following file systems are included:
</li><li><code>memFS:</code> in-memory file system (slower than mem; experimental; mainly used for testing the database engine itself). </li><li><code>memFS:</code> in-memory file system (slower than mem; experimental; mainly used for testing the database engine itself).
</li><li><code>memLZF:</code> compressing in-memory file system (slower than memFS but uses less memory; experimental; mainly used for testing the database engine itself). </li><li><code>memLZF:</code> compressing in-memory file system (slower than memFS but uses less memory; experimental; mainly used for testing the database engine itself).
</li><li><code>nioMemFS:</code> stores data outside of the VM's heap - useful for large memory DBs without incurring GC costs. </li><li><code>nioMemFS:</code> stores data outside of the VM's heap - useful for large memory DBs without incurring GC costs.
</li><li><code>nioMemLZF:</code> stores compressed data outside of the VM's heap - useful for large memory DBs without incurring GC costs. </li>
<li>
<code>nioMemLZF:</code> stores compressed data outside of the VM's heap - useful for large memory DBs without incurring GC costs.
<p>use "nioMemLZF:12:" to tweak the % of blocks that are stored uncompressed. If you size this to your working set correctly, compressed storage is roughly the same performance as uncompressed. The default value is 1%.
</li></ul> </li></ul>
<p> <p>
As an example, to use the the <code>nio</code> file system, use the following database URL: As an example, to use the the <code>nio</code> file system, use the following database URL:
......
...@@ -21,6 +21,10 @@ Change Log ...@@ -21,6 +21,10 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>The "nioMemLZF" filesystem now supports an extra option "nioMemLZF:12:" to tweak the size of the compress later cache.
</li>
<li>Various multi-threading fixes and optimisations to the "nioMemLZF" filesystem.
</li>
<li><strong>[API CHANGE]</strong> #439: the JDBC type of TIMESTAMP WITH TIME ZONE <li><strong>[API CHANGE]</strong> #439: the JDBC type of TIMESTAMP WITH TIME ZONE
changed from Types.OTHER (1111) to Types.TIMESTAMP_WITH_TIMEZONE (2014) changed from Types.OTHER (1111) to Types.TIMESTAMP_WITH_TIMEZONE (2014)
</li> </li>
......
...@@ -33,6 +33,7 @@ public class FilePathNioMem extends FilePath { ...@@ -33,6 +33,7 @@ public class FilePathNioMem extends FilePath {
private static final TreeMap<String, FileNioMemData> MEMORY_FILES = private static final TreeMap<String, FileNioMemData> MEMORY_FILES =
new TreeMap<String, FileNioMemData>(); new TreeMap<String, FileNioMemData>();
float compressLaterCachePercent = 1;
@Override @Override
public FilePathNioMem getPath(String path) { public FilePathNioMem getPath(String path) {
...@@ -184,14 +185,14 @@ public class FilePathNioMem extends FilePath { ...@@ -184,14 +185,14 @@ public class FilePathNioMem extends FilePath {
synchronized (MEMORY_FILES) { synchronized (MEMORY_FILES) {
FileNioMemData m = MEMORY_FILES.get(name); FileNioMemData m = MEMORY_FILES.get(name);
if (m == null) { if (m == null) {
m = new FileNioMemData(name, compressed()); m = new FileNioMemData(name, compressed(), compressLaterCachePercent);
MEMORY_FILES.put(name, m); MEMORY_FILES.put(name, m);
} }
return m; return m;
} }
} }
private boolean isRoot() { protected boolean isRoot() {
return name.equals(getScheme() + ":"); return name.equals(getScheme() + ":");
} }
...@@ -204,7 +205,7 @@ public class FilePathNioMem extends FilePath { ...@@ -204,7 +205,7 @@ public class FilePathNioMem extends FilePath {
*/ */
protected static String getCanonicalPath(String fileName) { protected static String getCanonicalPath(String fileName) {
fileName = fileName.replace('\\', '/'); fileName = fileName.replace('\\', '/');
int idx = fileName.indexOf(':') + 1; int idx = fileName.lastIndexOf(':') + 1;
if (fileName.length() > idx && fileName.charAt(idx) != '/') { if (fileName.length() > idx && fileName.charAt(idx) != '/') {
fileName = fileName.substring(0, idx) + "/" + fileName.substring(idx); fileName = fileName.substring(0, idx) + "/" + fileName.substring(idx);
} }
...@@ -219,7 +220,7 @@ public class FilePathNioMem extends FilePath { ...@@ -219,7 +220,7 @@ public class FilePathNioMem extends FilePath {
/** /**
* Whether the file should be compressed. * Whether the file should be compressed.
* *
* @return if it should be compressed. * @return true if it should be compressed.
*/ */
boolean compressed() { boolean compressed() {
return false; return false;
...@@ -239,11 +240,25 @@ class FilePathNioMemLZF extends FilePathNioMem { ...@@ -239,11 +240,25 @@ class FilePathNioMemLZF extends FilePathNioMem {
@Override @Override
public FilePathNioMem getPath(String path) { public FilePathNioMem getPath(String path) {
FilePathNioMemLZF p = new FilePathNioMemLZF(); if (!path.startsWith(getScheme())) {
throw new IllegalArgumentException(path +
" doesn't start with " + getScheme());
}
int idx1 = path.indexOf(":");
int idx2 = path.lastIndexOf(":");
final FilePathNioMemLZF p = new FilePathNioMemLZF();
if (idx1 != -1 && idx1 != idx2) {
p.compressLaterCachePercent = Float.parseFloat(path.substring(idx1 + 1, idx2));
}
p.name = getCanonicalPath(path); p.name = getCanonicalPath(path);
return p; return p;
} }
@Override
protected boolean isRoot() {
return name.lastIndexOf(":") == name.length() - 1;
}
@Override @Override
public String getScheme() { public String getScheme() {
return "nioMemLZF"; return "nioMemLZF";
...@@ -396,7 +411,7 @@ class FileNioMem extends FileBase { ...@@ -396,7 +411,7 @@ class FileNioMem extends FileBase {
*/ */
class FileNioMemData { class FileNioMemData {
private static final int CACHE_SIZE = 8; private static final int CACHE_MIN_SIZE = 8;
private static final int BLOCK_SIZE_SHIFT = 16; private static final int BLOCK_SIZE_SHIFT = 16;
private static final int BLOCK_SIZE = 1 << BLOCK_SIZE_SHIFT; private static final int BLOCK_SIZE = 1 << BLOCK_SIZE_SHIFT;
...@@ -418,11 +433,12 @@ class FileNioMemData { ...@@ -418,11 +433,12 @@ class FileNioMemData {
}; };
private final CompressLaterCache<CompressItem, CompressItem> compressLaterCache = private final CompressLaterCache<CompressItem, CompressItem> compressLaterCache =
new CompressLaterCache<CompressItem, CompressItem>(CACHE_SIZE); new CompressLaterCache<CompressItem, CompressItem>(CACHE_MIN_SIZE);
private String name; private String name;
private final int nameHashCode; private final int nameHashCode;
private final boolean compress; private final boolean compress;
private final float compressLaterCachePercent;
private long length; private long length;
private AtomicReference<ByteBuffer>[] buffers; private AtomicReference<ByteBuffer>[] buffers;
private long lastModified; private long lastModified;
...@@ -440,10 +456,11 @@ class FileNioMemData { ...@@ -440,10 +456,11 @@ class FileNioMemData {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
FileNioMemData(String name, boolean compress) { FileNioMemData(String name, boolean compress, float compressLaterCachePercent) {
this.name = name; this.name = name;
this.nameHashCode = name.hashCode(); this.nameHashCode = name.hashCode();
this.compress = compress; this.compress = compress;
this.compressLaterCachePercent = compressLaterCachePercent;
buffers = new AtomicReference[0]; buffers = new AtomicReference[0];
lastModified = System.currentTimeMillis(); lastModified = System.currentTimeMillis();
} }
...@@ -491,7 +508,7 @@ class FileNioMemData { ...@@ -491,7 +508,7 @@ class FileNioMemData {
static class CompressLaterCache<K, V> extends LinkedHashMap<K, V> { static class CompressLaterCache<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final int size; private int size;
CompressLaterCache(int size) { CompressLaterCache(int size) {
super(size, (float) 0.75, true); super(size, (float) 0.75, true);
...@@ -507,6 +524,10 @@ class FileNioMemData { ...@@ -507,6 +524,10 @@ class FileNioMemData {
c.data.compressPage(c.page); c.data.compressPage(c.page);
return true; return true;
} }
public void setCacheSize(int size) {
this.size = size;
}
} }
/** /**
...@@ -650,6 +671,7 @@ class FileNioMemData { ...@@ -650,6 +671,7 @@ class FileNioMemData {
} }
buffers = newBuffers; buffers = newBuffers;
} }
compressLaterCache.setCacheSize(Math.max(CACHE_MIN_SIZE, (int)(blocks * compressLaterCachePercent / 100)));
} }
/** /**
......
...@@ -23,7 +23,6 @@ import java.util.List; ...@@ -23,7 +23,6 @@ import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import org.h2.dev.fs.FilePathZip2; import org.h2.dev.fs.FilePathZip2;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.mvstore.DataUtils; import org.h2.mvstore.DataUtils;
...@@ -86,6 +85,7 @@ public class TestFileSystem extends TestBase { ...@@ -86,6 +85,7 @@ public class TestFileSystem extends TestBase {
testFileSystem("memLZF:"); testFileSystem("memLZF:");
testFileSystem("nioMemFS:"); testFileSystem("nioMemFS:");
testFileSystem("nioMemLZF:"); testFileSystem("nioMemLZF:");
testFileSystem("nioMemLZF:12:"); // 12% compressLaterCache
testFileSystem("rec:memFS:"); testFileSystem("rec:memFS:");
testUserHome(); testUserHome();
try { try {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论