提交 237b1a55 authored 作者: Thomas Mueller's avatar Thomas Mueller

MVStore table engine - now almost as fast as the page store (WIP)

上级 c9e973a3
......@@ -23,8 +23,8 @@ import org.h2.jdbc.JdbcConnection;
import org.h2.message.DbException;
import org.h2.message.Trace;
import org.h2.message.TraceSystem;
import org.h2.mvstore.db.TransactionStore;
import org.h2.mvstore.db.TransactionStore.Transaction;
import org.h2.mvstore.db.TransactionStore2;
import org.h2.mvstore.db.TransactionStore2.Transaction;
import org.h2.result.ResultInterface;
import org.h2.result.Row;
import org.h2.schema.Schema;
......@@ -106,7 +106,6 @@ public class Session extends SessionWithState {
private SmallLRUCache<String, Command> queryCache;
private Transaction transaction;
private long startStatement = -1;
private long statementVersion;
public Session(Database database, User user, int id) {
this.database = database;
......@@ -1258,20 +1257,19 @@ public class Session extends SessionWithState {
* @param store the store
* @return the transaction
*/
public Transaction getTransaction(TransactionStore store) {
public Transaction getTransaction(TransactionStore2 store) {
if (transaction == null) {
transaction = store.begin();
statementVersion = -1;
startStatement = -1;
}
return transaction;
}
public long getStatementVersion() {
public long getStatementSavepoint() {
if (startStatement == -1) {
startStatement = transaction.setSavepoint();
statementVersion = transaction.getCurrentVersion();
}
return statementVersion;
return startStatement;
}
}
......@@ -35,7 +35,9 @@ public class MVDelegateIndex extends BaseIndex {
}
}
static int count;
public void add(Session session, Row row) {
count++;
// nothing to do
}
......
......@@ -18,8 +18,8 @@ import org.h2.index.Cursor;
import org.h2.index.IndexType;
import org.h2.message.DbException;
import org.h2.mvstore.MVMap;
import org.h2.mvstore.db.TransactionStore.Transaction;
import org.h2.mvstore.db.TransactionStore.TransactionMap;
import org.h2.mvstore.db.TransactionStore2.Transaction;
import org.h2.mvstore.db.TransactionStore2.TransactionMap;
import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.result.SortOrder;
......@@ -37,7 +37,7 @@ public class MVPrimaryIndex extends BaseIndex {
private final MVTable mvTable;
private String mapName;
private MVMap.Builder<Value, Value> mapBuilder;
private TransactionMap<Value, Value> dataMap;
private long lastKey;
private int mainIndexColumn = -1;
......@@ -54,12 +54,12 @@ public class MVPrimaryIndex extends BaseIndex {
ValueDataType valueType = new ValueDataType(
db.getCompareMode(), db, sortTypes);
mapName = getName() + "_" + getId();
mapBuilder = new MVMap.Builder<Value, Value>().
MVMap.Builder<Value, Value> mapBuilder = new MVMap.Builder<Value, Value>().
keyType(keyType).
valueType(valueType);
TransactionMap<Value, Value> map = getMap(null);
Value k = map.lastKey();
map.getTransaction().commit();
dataMap = mvTable.getTransaction(null).openMap(mapName, mapBuilder);
Value k = dataMap.lastKey();
dataMap.getTransaction().commit();
lastKey = k == null ? 0 : k.getLong();
}
......@@ -108,10 +108,6 @@ public class MVPrimaryIndex extends BaseIndex {
Long c = row.getValue(mainIndexColumn).getLong();
row.setKey(c);
}
Value[] array = new Value[columns.length];
for (int i = 0; i < array.length; i++) {
array[i] = row.getValue(i);
}
TransactionMap<Value, Value> map = getMap(session);
if (map.containsKey(ValueLong.get(row.getKey()))) {
String sql = "PRIMARY KEY ON " + table.getSQL();
......@@ -122,7 +118,7 @@ public class MVPrimaryIndex extends BaseIndex {
e.setSource(this);
throw e;
}
map.put(ValueLong.get(row.getKey()), ValueArray.get(array));
map.put(ValueLong.get(row.getKey()), ValueArray.get(row.getValueList()));
lastKey = Math.max(lastKey, row.getKey());
}
......@@ -287,6 +283,25 @@ public class MVPrimaryIndex extends BaseIndex {
return new MVStoreCursor(session, map.keyIterator(ValueLong.get(first)), last);
}
public boolean isRowIdIndex() {
return true;
}
/**
* Get the map to store the data.
*
* @param session the session
* @return the map
*/
TransactionMap<Value, Value> getMap(Session session) {
if (session == null) {
return dataMap;
}
Transaction t = mvTable.getTransaction(session);
long savepoint = session.getStatementSavepoint();
return dataMap.getInstance(t, savepoint);
}
/**
* A cursor.
*/
......@@ -337,23 +352,4 @@ public class MVPrimaryIndex extends BaseIndex {
}
public boolean isRowIdIndex() {
return true;
}
/**
* Get the map to store the data.
*
* @param session the session
* @return the map
*/
TransactionMap<Value, Value> getMap(Session session) {
if (session == null) {
return mvTable.getTransaction(null).openMap(mapName, -1, mapBuilder);
}
Transaction t = mvTable.getTransaction(session);
long version = session.getStatementVersion();
return t.openMap(mapName, version, mapBuilder);
}
}
......@@ -17,8 +17,8 @@ import org.h2.index.Cursor;
import org.h2.index.IndexType;
import org.h2.message.DbException;
import org.h2.mvstore.MVMap;
import org.h2.mvstore.db.TransactionStore.Transaction;
import org.h2.mvstore.db.TransactionStore.TransactionMap;
import org.h2.mvstore.db.TransactionStore2.Transaction;
import org.h2.mvstore.db.TransactionStore2.TransactionMap;
import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.result.SortOrder;
......@@ -42,7 +42,7 @@ public class MVSecondaryIndex extends BaseIndex {
private final int keyColumns;
private String mapName;
private MVMap.Builder<Value, Value> mapBuilder;
private TransactionMap<Value, Value> dataMap;
public MVSecondaryIndex(Database db, MVTable table, int id, String indexName,
IndexColumn[] columns, IndexType indexType) {
......@@ -63,9 +63,10 @@ public class MVSecondaryIndex extends BaseIndex {
ValueDataType keyType = new ValueDataType(
db.getCompareMode(), db, sortTypes);
ValueDataType valueType = new ValueDataType(null, null, null);
mapBuilder = new MVMap.Builder<Value, Value>().
MVMap.Builder<Value, Value> mapBuilder = new MVMap.Builder<Value, Value>().
keyType(keyType).
valueType(valueType);
dataMap = mvTable.getTransaction(null).openMap(mapName, mapBuilder);
}
private static void checkIndexColumnTypes(IndexColumn[] columns) {
......@@ -247,6 +248,21 @@ public class MVSecondaryIndex extends BaseIndex {
// ok
}
/**
* Get the map to store the data.
*
* @param session the session
* @return the map
*/
TransactionMap<Value, Value> getMap(Session session) {
if (session == null) {
return dataMap;
}
Transaction t = mvTable.getTransaction(session);
long savepoint = session.getStatementSavepoint();
return dataMap.getInstance(t, savepoint);
}
/**
* A cursor.
*/
......@@ -308,19 +324,4 @@ public class MVSecondaryIndex extends BaseIndex {
}
/**
* Get the map to store the data.
*
* @param session the session
* @return the map
*/
TransactionMap<Value, Value> getMap(Session session) {
if (session == null) {
return mvTable.getTransaction(null).openMap(mapName, -1, mapBuilder);
}
Transaction t = mvTable.getTransaction(session);
long version = session.getStatementVersion();
return t.openMap(mapName, version, mapBuilder);
}
}
......@@ -28,7 +28,7 @@ import org.h2.index.IndexType;
import org.h2.index.MultiVersionIndex;
import org.h2.message.DbException;
import org.h2.message.Trace;
import org.h2.mvstore.db.TransactionStore.Transaction;
import org.h2.mvstore.db.TransactionStore2.Transaction;
import org.h2.result.Row;
import org.h2.result.SortOrder;
import org.h2.schema.SchemaObject;
......@@ -48,7 +48,7 @@ import org.h2.value.Value;
public class MVTable extends TableBase {
private final String storeName;
private final TransactionStore store;
private final TransactionStore2 store;
private MVPrimaryIndex primaryIndex;
private ArrayList<Index> indexes = New.arrayList();
private long lastModificationId;
......@@ -68,7 +68,7 @@ public class MVTable extends TableBase {
*/
private boolean waitForLock;
public MVTable(CreateTableData data, String storeName, TransactionStore store) {
public MVTable(CreateTableData data, String storeName, TransactionStore2 store) {
super(data);
nextAnalyze = database.getSettings().analyzeAuto;
this.storeName = storeName;
......@@ -571,7 +571,8 @@ public class MVTable extends TableBase {
nextAnalyze = n;
}
int rows = session.getDatabase().getSettings().analyzeSample;
Analyze.analyzeTable(session, this, rows, false);
int test;
// Analyze.analyzeTable(session, this, rows, false);
}
@Override
......@@ -686,7 +687,7 @@ public class MVTable extends TableBase {
return session.getTransaction(store);
}
public TransactionStore getStore() {
public TransactionStore2 getStore() {
return store;
}
......
......@@ -142,12 +142,12 @@ public class MVTableEngine implements TableEngine {
/**
* The transaction store.
*/
private final TransactionStore transactionStore;
private final TransactionStore2 transactionStore;
public Store(Database db, MVStore store) {
this.db = db;
this.store = store;
this.transactionStore = new TransactionStore(store,
this.transactionStore = new TransactionStore2(store,
new ValueDataType(null, null, null));
}
......@@ -155,7 +155,7 @@ public class MVTableEngine implements TableEngine {
return store;
}
public TransactionStore getTransactionStore() {
public TransactionStore2 getTransactionStore() {
return transactionStore;
}
......
......@@ -164,4 +164,8 @@ public class Row implements SearchRow {
return deleted;
}
public Value[] getValueList() {
return data;
}
}
......@@ -17,6 +17,7 @@ import org.h2.engine.Constants;
import org.h2.mvstore.db.MVTableEngine;
import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase;
import org.h2.util.Profiler;
import org.h2.util.Task;
/**
......@@ -38,23 +39,26 @@ public class TestMVTableEngine extends TestBase {
testEncryption();
testReadOnly();
testReuseDiskSpace();
testDataTypes();
// testDataTypes();
testLocking();
testSimple();
// testSimple();
}
private void testSpeed() throws Exception {
String dbName;
for (int i = 0; i < 5; i++) {
for (int i = 0; i < 10; i++) {
dbName = "mvstore";
dbName += ";LOCK_MODE=0";
// dbName += ";LOCK_MODE=0";
testSpeed(dbName);
// Profiler prof = new Profiler().startCollecting();
int tes;
//Profiler prof = new Profiler().startCollecting();
dbName = "mvstore" +
";DEFAULT_TABLE_ENGINE=org.h2.mvstore.db.MVTableEngine";
// dbName += ";LOCK_MODE=0";
testSpeed(dbName);
// System.out.println(prof.getTop(10));
//System.out.println(prof.getTop(10));
}
FileUtils.deleteRecursive(getBaseDir(), true);
}
private void testSpeed(String dbName) throws Exception {
......@@ -69,15 +73,14 @@ public class TestMVTableEngine extends TestBase {
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");
prep.setString(2, "Hello World xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
long time = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
for (int i = 0; i < 200000; 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 {
......@@ -375,7 +378,7 @@ public class TestMVTableEngine extends TestBase {
stat.execute("insert into test(id, name) values(10, 'Hello')");
fail();
} catch (SQLException e) {
assertEquals(ErrorCode.DUPLICATE_KEY_1, e.getErrorCode());
assertEquals(e.toString(), ErrorCode.DUPLICATE_KEY_1, e.getErrorCode());
}
rs = stat.executeQuery("select min(id), max(id), min(name), max(name) from test");
......
......@@ -64,21 +64,19 @@ public class TestTransactionStore extends TestBase {
Transaction tx;
TransactionMap<String, String> m;
long startUpdate;
long version;
tx = ts.begin();
// start of statement
// create table test
startUpdate = tx.setSavepoint();
version = s.getCurrentVersion();
tx.openMap("test", version);
m = tx.openMap("test");
m.setSavepoint(startUpdate);
// start of statement
// insert into test(id, name) values(1, 'Hello'), (2, 'World')
startUpdate = tx.setSavepoint();
version = s.getCurrentVersion();
m = tx.openMap("test", version);
m.setSavepoint(startUpdate);
assertTrue(m.trySet("1", "Hello", true));
assertTrue(m.trySet("2", "World", true));
// not seen yet (within the same statement)
......@@ -87,13 +85,12 @@ public class TestTransactionStore extends TestBase {
// start of statement
startUpdate = tx.setSavepoint();
version = s.getCurrentVersion();
// now we see the newest version
m = tx.openMap("test", version);
m.setSavepoint(startUpdate);
assertEquals("Hello", m.get("1"));
assertEquals("World", m.get("2"));
// update test set primaryKey = primaryKey + 1
// (this is usually a tricky cases)
// (this is usually a tricky case)
assertEquals("Hello", m.get("1"));
assertTrue(m.trySet("1", null, true));
assertTrue(m.trySet("2", "Hello", true));
......@@ -110,8 +107,7 @@ public class TestTransactionStore extends TestBase {
// start of statement
startUpdate = tx.setSavepoint();
version = s.getCurrentVersion();
m = tx.openMap("test", version);
m.setSavepoint(startUpdate);
// select * from test
assertNull(m.get("1"));
assertEquals("Hello", m.get("2"));
......@@ -119,8 +115,7 @@ public class TestTransactionStore extends TestBase {
// start of statement
startUpdate = tx.setSavepoint();
version = s.getCurrentVersion();
m = tx.openMap("test", version);
m.setSavepoint(startUpdate);
// update test set id = 1
// should fail: duplicate key
assertTrue(m.trySet("2", null, true));
......@@ -129,8 +124,8 @@ public class TestTransactionStore extends TestBase {
assertFalse(m.trySet("1", "World", true));
tx.rollbackToSavepoint(startUpdate);
version = s.getCurrentVersion();
m = tx.openMap("test", version);
startUpdate = tx.setSavepoint();
m.setSavepoint(startUpdate);
assertNull(m.get("1"));
assertEquals("Hello", m.get("2"));
assertEquals("World", m.get("3"));
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论