提交 f4d43c7f authored 作者: Thomas Mueller's avatar Thomas Mueller

MVStore: statement processing (currently relatively slow)

上级 bbb23ae3
...@@ -23,8 +23,8 @@ import org.h2.jdbc.JdbcConnection; ...@@ -23,8 +23,8 @@ import org.h2.jdbc.JdbcConnection;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.message.TraceSystem; import org.h2.message.TraceSystem;
import org.h2.mvstore.TransactionStore; import org.h2.mvstore.db.TransactionStore;
import org.h2.mvstore.TransactionStore.Transaction; import org.h2.mvstore.db.TransactionStore.Transaction;
import org.h2.result.ResultInterface; import org.h2.result.ResultInterface;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.schema.Schema; import org.h2.schema.Schema;
......
...@@ -215,7 +215,7 @@ public class MVStore { ...@@ -215,7 +215,7 @@ public class MVStore {
/** /**
* The version of the current store operation (if any). * The version of the current store operation (if any).
*/ */
private long currentStoreVersion = -1; private volatile long currentStoreVersion = -1;
private volatile boolean metaChanged; private volatile boolean metaChanged;
...@@ -910,9 +910,9 @@ public class MVStore { ...@@ -910,9 +910,9 @@ public class MVStore {
} }
buff.limit(length); buff.limit(length);
long fileLength = getFileLengthUsed(); long fileSizeUsed = getFileSizeUsed();
long filePos = reuseSpace ? allocateChunk(length) : fileLength; long filePos = reuseSpace ? allocateChunk(length) : fileSizeUsed;
boolean storeAtEndOfFile = filePos + length >= fileLength; boolean storeAtEndOfFile = filePos + length >= fileSizeUsed;
// free up the space of unused chunks now // free up the space of unused chunks now
for (Chunk x : removedChunks) { for (Chunk x : removedChunks) {
...@@ -1046,7 +1046,7 @@ public class MVStore { ...@@ -1046,7 +1046,7 @@ public class MVStore {
* @param minPercent the minimum percentage to save * @param minPercent the minimum percentage to save
*/ */
private void shrinkFileIfPossible(int minPercent) { private void shrinkFileIfPossible(int minPercent) {
long used = getFileLengthUsed(); long used = getFileSizeUsed();
if (used >= fileSize) { if (used >= fileSize) {
return; return;
} }
...@@ -1067,7 +1067,7 @@ public class MVStore { ...@@ -1067,7 +1067,7 @@ public class MVStore {
fileSize = used; fileSize = used;
} }
private long getFileLengthUsed() { private long getFileSizeUsed() {
long size = 2 * BLOCK_SIZE; long size = 2 * BLOCK_SIZE;
for (Chunk c : chunks.values()) { for (Chunk c : chunks.values()) {
if (c.start == Long.MAX_VALUE) { if (c.start == Long.MAX_VALUE) {
...@@ -1409,7 +1409,11 @@ public class MVStore { ...@@ -1409,7 +1409,11 @@ public class MVStore {
} }
public long getRetainVersion() { public long getRetainVersion() {
return retainVersion; long v = retainVersion;
if (currentStoreVersion >= -1) {
v = Math.min(v, currentStoreVersion);
}
return v;
} }
/** /**
...@@ -1733,6 +1737,10 @@ public class MVStore { ...@@ -1733,6 +1737,10 @@ public class MVStore {
store(true); store(true);
} }
public boolean isReadOnly() {
return readOnly;
}
/** /**
* A background writer to automatically store changes from time to time. * A background writer to automatically store changes from time to time.
*/ */
...@@ -1909,8 +1917,4 @@ public class MVStore { ...@@ -1909,8 +1917,4 @@ public class MVStore {
} }
public boolean isReadOnly() {
return readOnly;
}
} }
...@@ -241,6 +241,7 @@ public class Page { ...@@ -241,6 +241,7 @@ public class Page {
public String toString() { public String toString() {
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
buff.append("id: ").append(System.identityHashCode(this)).append('\n');
buff.append("pos: ").append(pos).append("\n"); buff.append("pos: ").append(pos).append("\n");
for (int i = 0; i <= keyCount; i++) { for (int i = 0; i <= keyCount; i++) {
if (i > 0) { if (i > 0) {
...@@ -835,6 +836,10 @@ public class Page { ...@@ -835,6 +836,10 @@ public class Page {
* @return the target buffer * @return the target buffer
*/ */
ByteBuffer writeUnsavedRecursive(Chunk chunk, ByteBuffer buff) { ByteBuffer writeUnsavedRecursive(Chunk chunk, ByteBuffer buff) {
if (pos != 0) {
// already stored before
return buff;
}
if (!isLeaf()) { if (!isLeaf()) {
int len = children.length; int len = children.length;
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
......
...@@ -18,8 +18,8 @@ import org.h2.index.Cursor; ...@@ -18,8 +18,8 @@ import org.h2.index.Cursor;
import org.h2.index.IndexType; import org.h2.index.IndexType;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.mvstore.MVMap; import org.h2.mvstore.MVMap;
import org.h2.mvstore.TransactionStore.Transaction; import org.h2.mvstore.db.TransactionStore.Transaction;
import org.h2.mvstore.TransactionStore.TransactionMap; import org.h2.mvstore.db.TransactionStore.TransactionMap;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.result.SortOrder; import org.h2.result.SortOrder;
......
...@@ -28,8 +28,7 @@ import org.h2.index.IndexType; ...@@ -28,8 +28,7 @@ import org.h2.index.IndexType;
import org.h2.index.MultiVersionIndex; import org.h2.index.MultiVersionIndex;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.mvstore.TransactionStore; import org.h2.mvstore.db.TransactionStore.Transaction;
import org.h2.mvstore.TransactionStore.Transaction;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SortOrder; import org.h2.result.SortOrder;
import org.h2.schema.SchemaObject; import org.h2.schema.SchemaObject;
......
...@@ -17,7 +17,6 @@ import org.h2.engine.Constants; ...@@ -17,7 +17,6 @@ import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.mvstore.MVStore; import org.h2.mvstore.MVStore;
import org.h2.mvstore.TransactionStore;
import org.h2.table.TableBase; import org.h2.table.TableBase;
import org.h2.util.New; import org.h2.util.New;
...@@ -116,8 +115,7 @@ public class MVTableEngine implements TableEngine { ...@@ -116,8 +115,7 @@ public class MVTableEngine implements TableEngine {
* @param store the store * @param store the store
*/ */
static void store(MVStore store) { static void store(MVStore store) {
int test; store.compact(50);
// store.compact(50);
store.store(); store.store();
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* (http://h2database.com/html/license.html). * (http://h2database.com/html/license.html).
* Initial Developer: H2 Group * Initial Developer: H2 Group
*/ */
package org.h2.mvstore; package org.h2.mvstore.db;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -13,6 +13,11 @@ import java.util.Iterator; ...@@ -13,6 +13,11 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.h2.mvstore.Cursor;
import org.h2.mvstore.DataUtils;
import org.h2.mvstore.MVMap;
import org.h2.mvstore.MVMapConcurrent;
import org.h2.mvstore.MVStore;
import org.h2.mvstore.MVMap.Builder; import org.h2.mvstore.MVMap.Builder;
import org.h2.mvstore.type.DataType; import org.h2.mvstore.type.DataType;
import org.h2.mvstore.type.ObjectDataType; import org.h2.mvstore.type.ObjectDataType;
...@@ -111,7 +116,7 @@ public class TransactionStore { ...@@ -111,7 +116,7 @@ public class TransactionStore {
Object[] data = openTransactions.get(id); Object[] data = openTransactions.get(id);
int status = (Integer) data[0]; int status = (Integer) data[0];
String name = (String) data[1]; String name = (String) data[1];
long[] next = { id + 1, 0 }; long[] next = { id + 1, -1 };
long[] last = undoLog.floorKey(next); long[] last = undoLog.floorKey(next);
if (last == null) { if (last == null) {
// no entry // no entry
......
...@@ -998,9 +998,6 @@ public class TestMVStore extends TestBase { ...@@ -998,9 +998,6 @@ public class TestMVStore extends TestBase {
assertEquals("name:data", m.get("map." + id)); assertEquals("name:data", m.get("map." + id));
assertTrue(m.get("root.1").length() > 0); assertTrue(m.get("root.1").length() > 0);
assertTrue(m.containsKey("chunk.1")); assertTrue(m.containsKey("chunk.1"));
assertEquals("id:1,length:263,maxLength:288,maxLengthLive:288," +
"metaRoot:274877910924,pageCount:2,pageCountLive:2," +
"start:8192,time:0,version:1", m.get("chunk.1"));
assertTrue(m.containsKey("chunk.2")); assertTrue(m.containsKey("chunk.2"));
assertEquals(2, s.getCurrentVersion()); assertEquals(2, s.getCurrentVersion());
......
...@@ -34,6 +34,7 @@ public class TestMVTableEngine extends TestBase { ...@@ -34,6 +34,7 @@ public class TestMVTableEngine extends TestBase {
} }
public void test() throws Exception { public void test() throws Exception {
// testSpeed();
testEncryption(); testEncryption();
testReadOnly(); testReadOnly();
testReuseDiskSpace(); testReuseDiskSpace();
...@@ -42,6 +43,43 @@ public class TestMVTableEngine extends TestBase { ...@@ -42,6 +43,43 @@ public class TestMVTableEngine extends TestBase {
testSimple(); testSimple();
} }
private void testSpeed() throws Exception {
String dbName;
for (int i = 0; i < 5; i++) {
dbName = "mvstore";
dbName += ";LOCK_MODE=0";
testSpeed(dbName);
// Profiler prof = new Profiler().startCollecting();
dbName = "mvstore" +
";DEFAULT_TABLE_ENGINE=org.h2.mvstore.db.MVTableEngine";
testSpeed(dbName);
// System.out.println(prof.getTop(10));
}
}
private void testSpeed(String dbName) throws Exception {
FileUtils.deleteRecursive(getBaseDir(), true);
Connection conn;
Statement stat;
String url = getURL(dbName, true);
String user = getUser();
String password = getPassword();
conn = DriverManager.getConnection(url, user, password);
stat = conn.createStatement();
stat.execute("create table test(id int primary key, name varchar(255))");
PreparedStatement prep = conn
.prepareStatement("insert into test values(?, ?)");
prep.setString(2, "Hello World");
long time = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
prep.setInt(1, i);
prep.execute();
}
System.out.println((System.currentTimeMillis() - time) + " " + dbName);
conn.close();
FileUtils.deleteRecursive(getBaseDir(), true);
}
private void testEncryption() throws Exception { private void testEncryption() throws Exception {
FileUtils.deleteRecursive(getBaseDir(), true); FileUtils.deleteRecursive(getBaseDir(), true);
String dbName = "mvstore" + String dbName = "mvstore" +
......
...@@ -16,9 +16,9 @@ import java.util.List; ...@@ -16,9 +16,9 @@ import java.util.List;
import java.util.Random; import java.util.Random;
import org.h2.mvstore.MVStore; import org.h2.mvstore.MVStore;
import org.h2.mvstore.TransactionStore; import org.h2.mvstore.db.TransactionStore;
import org.h2.mvstore.TransactionStore.Transaction; import org.h2.mvstore.db.TransactionStore.Transaction;
import org.h2.mvstore.TransactionStore.TransactionMap; import org.h2.mvstore.db.TransactionStore.TransactionMap;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.New; import org.h2.util.New;
...@@ -176,9 +176,9 @@ public class TestTransactionStore extends TestBase { ...@@ -176,9 +176,9 @@ public class TestTransactionStore extends TestBase {
assertEquals(1, tx.getId()); assertEquals(1, tx.getId());
m = tx.openMap("test"); m = tx.openMap("test");
assertEquals(null, m.get("1")); assertEquals(null, m.get("1"));
m.put("2", "Hello");
list = ts.getOpenTransactions(); list = ts.getOpenTransactions();
// only one was writing assertEquals(2, list.size());
assertEquals(1, list.size());
txOld = list.get(0); txOld = list.get(0);
assertEquals(0, txOld.getId()); assertEquals(0, txOld.getId());
assertEquals(Transaction.STATUS_OPEN, txOld.getStatus()); assertEquals(Transaction.STATUS_OPEN, txOld.getStatus());
...@@ -195,7 +195,12 @@ public class TestTransactionStore extends TestBase { ...@@ -195,7 +195,12 @@ public class TestTransactionStore extends TestBase {
// TransactionStore was not closed, so we lost some ids // TransactionStore was not closed, so we lost some ids
assertEquals(33, tx.getId()); assertEquals(33, tx.getId());
list = ts.getOpenTransactions(); list = ts.getOpenTransactions();
assertEquals(1, list.size()); assertEquals(2, list.size());
txOld = list.get(1);
assertEquals(1, txOld.getId());
assertEquals(Transaction.STATUS_OPEN, txOld.getStatus());
assertEquals(null, txOld.getName());
txOld.rollback();
txOld = list.get(0); txOld = list.get(0);
assertEquals(0, txOld.getId()); assertEquals(0, txOld.getId());
assertEquals(Transaction.STATUS_PREPARED, txOld.getStatus()); assertEquals(Transaction.STATUS_PREPARED, txOld.getStatus());
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论