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

New experimental page store.

上级 d83c77cd
......@@ -11,6 +11,7 @@ import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.message.TraceSystem;
import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.store.DataPage;
......
......@@ -8,6 +8,7 @@ package org.h2.index;
import java.sql.SQLException;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.message.Message;
import org.h2.result.SearchRow;
import org.h2.store.DataPage;
......@@ -70,7 +71,17 @@ class PageBtreeLeaf extends PageBtree {
return (entryCount / 2) + 1;
}
onlyPosition = true;
// change the offsets (now storing only positions)
int o = pageSize;
for (int i = 0; i < entryCount; i++) {
o -= index.getRowSize(data, getRow(i), onlyPosition);
offsets[i] = o;
}
last = entryCount == 0 ? pageSize : offsets[entryCount - 1];
rowLength = index.getRowSize(data, row, onlyPosition);
if (SysProperties.CHECK && last - rowLength < start + OFFSET_LENGTH) {
throw Message.throwInternalError();
}
}
written = false;
int offset = last - rowLength;
......
......@@ -7,6 +7,7 @@
package org.h2.index;
import java.sql.SQLException;
import org.h2.constant.SysProperties;
import org.h2.message.Message;
import org.h2.result.SearchRow;
import org.h2.store.DataPage;
......@@ -68,7 +69,6 @@ class PageBtreeNode extends PageBtree {
int pageSize = index.getPageStore().getPageSize();
int last = entryCount == 0 ? pageSize : offsets[entryCount - 1];
if (last - rowLength < start + CHILD_OFFSET_PAIR_LENGTH) {
int todoSplitAtLastInsertionPoint;
return (entryCount / 2) + 1;
}
return 0;
......@@ -86,9 +86,18 @@ class PageBtreeNode extends PageBtree {
int pageSize = index.getPageStore().getPageSize();
int last = entryCount == 0 ? pageSize : offsets[entryCount - 1];
if (last - rowLength < start + CHILD_OFFSET_PAIR_LENGTH) {
// TODO remap all children
onlyPosition = true;
// change the offsets (now storing only positions)
int o = pageSize;
for (int i = 0; i < entryCount; i++) {
o -= index.getRowSize(data, getRow(i), onlyPosition);
offsets[i] = o;
}
last = entryCount == 0 ? pageSize : offsets[entryCount - 1];
rowLength = index.getRowSize(data, row, onlyPosition);
if (SysProperties.CHECK && last - rowLength < start + CHILD_OFFSET_PAIR_LENGTH) {
throw Message.throwInternalError();
}
}
int offset = last - rowLength;
int[] newOffsets = new int[entryCount + 1];
......
......@@ -92,7 +92,6 @@ class PageDataLeaf extends PageData {
int pageSize = index.getPageStore().getPageSize();
int last = entryCount == 0 ? pageSize : offsets[entryCount - 1];
if (entryCount > 0 && last - rowLength < start + KEY_OFFSET_PAIR_LENGTH) {
int todoSplitAtLastInsertionPoint;
return (entryCount / 2) + 1;
}
int offset = last - rowLength;
......
......@@ -87,7 +87,6 @@ class PageDataNode extends PageData {
}
int maxEntries = (index.getPageStore().getPageSize() - ENTRY_START) / ENTRY_LENGTH;
if (entryCount >= maxEntries) {
int todoSplitAtLastInsertionPoint;
return entryCount / 2;
}
int pivot = page.getKey(splitPoint - 1);
......@@ -155,7 +154,6 @@ class PageDataNode extends PageData {
}
int getLastKey() throws SQLException {
int todoRemove;
return index.getPage(childPageIds[entryCount], getPos()).getLastKey();
}
......
......@@ -139,6 +139,7 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
store.updateRecord(newRoot, true, null);
root = newRoot;
}
row.setDeleted(false);
if (database.isMultiVersion()) {
if (delta == null) {
delta = New.hashSet();
......@@ -347,6 +348,13 @@ public class PageScanIndex extends BaseIndex implements RowIndex {
if (trace.isDebugEnabled()) {
trace.debug("close");
}
if (delta != null) {
delta.clear();
}
rowCountDiff = 0;
if (sessionRowCount != null) {
sessionRowCount.clear();
}
int todoWhyNotClose;
// store = null;
int writeRowCount;
......
......@@ -461,7 +461,6 @@ public class PageLog {
row.setLastLog(logId, logPos);
data.reset();
int todoWriteIntoOutputDirectly;
row.write(data);
out.write(add ? ADD : REMOVE);
out.writeInt(session.getId());
......
......@@ -112,6 +112,8 @@ public class PageStore implements CacheWriter {
// TODO PageData and PageBtree addRowTry: try to simplify
// TODO performance: don't save direct parent in btree nodes (only root)
// TODO space re-use: run TestPerformance multiple times, size should stay
// TODO when inserting many rows, do not split at (entryCount / 2) + 1
// TODO maybe split at the last insertion point
// TODO when removing DiskFile:
// remove CacheObject.blockCount
......@@ -1043,12 +1045,12 @@ public class PageStore implements CacheWriter {
public boolean isRecoveryRunning() {
return this.recoveryRunning;
}
private void checkOpen() throws SQLException {
if (file == null) {
throw Message.getSQLException(ErrorCode.SIMULATED_POWER_OFF);
}
}
}
......@@ -59,6 +59,7 @@ import org.h2.util.StringUtils;
import org.h2.util.TempFileDeleter;
import org.h2.util.Tool;
import org.h2.value.Value;
import org.h2.value.ValueInt;
import org.h2.value.ValueLob;
/**
......@@ -296,11 +297,10 @@ public class Recover extends Tool implements DataHandler {
}
/**
* Dumps the database.
* Dumps the contents of a database to a SQL script file.
*
* @param dir the directory
* @param db the database name (null for all databases)
* @throws SQLException
*/
public static void execute(String dir, String db) throws SQLException {
new Recover().process(dir, db);
......@@ -805,8 +805,8 @@ public class Recover extends Tool implements DataHandler {
break;
case Page.TYPE_DATA_NODE: {
int entries = s.readShortInt();
int recordCount = s.readInt();
writer.println("-- page " + page + ": data node " + (last ? "(last)" : "") + " entries: " + entries + " record: " + recordCount);
int rowCount = s.readInt();
writer.println("-- page " + page + ": data node " + (last ? "(last)" : "") + " entries: " + entries + " rowCount: " + rowCount);
break;
}
case Page.TYPE_DATA_LEAF: {
......@@ -819,16 +819,18 @@ public class Recover extends Tool implements DataHandler {
case Page.TYPE_BTREE_NODE:
writer.println("-- page " + page + ": btree node" + (last ? "(last)" : ""));
if (trace) {
dumpPageBtreeNode(writer, s);
dumpPageBtreeNode(writer, s, !last);
}
break;
case Page.TYPE_BTREE_LEAF:
case Page.TYPE_BTREE_LEAF: {
setStorage(s.readInt());
writer.println("-- page " + page + ": btree leaf " + (last ? "(last)" : "") + " table: " + storageId);
int entries = s.readShortInt();
writer.println("-- page " + page + ": btree leaf " + (last ? "(last)" : "") + " table: " + storageId + " entries: " + entries);
if (trace) {
dumpPageBtreeLeaf(writer, s);
dumpPageBtreeLeaf(writer, s, entries, !last);
}
break;
}
case Page.TYPE_FREE_LIST:
writer.println("-- page " + page + ": free list " + (last ? "(last)" : ""));
free += dumpPageFreeList(writer, s, pageSize, page, pageCount);
......@@ -1031,7 +1033,7 @@ public class Recover extends Tool implements DataHandler {
}
}
private void dumpPageBtreeNode(PrintWriter writer, DataPage s) {
private void dumpPageBtreeNode(PrintWriter writer, DataPage s, boolean positionOnly) {
int entryCount = s.readShortInt();
int rowCount = s.readInt();
int[] children = new int[entryCount + 1];
......@@ -1046,11 +1048,15 @@ public class Recover extends Tool implements DataHandler {
s.setPos(off);
int pos = s.readInt();
Value data;
try {
data = s.readValue();
} catch (Throwable e) {
writeDataError(writer, "exception " + e, s.getBytes(), blockCount);
continue;
if (positionOnly) {
data = ValueInt.get(pos);
} else {
try {
data = s.readValue();
} catch (Throwable e) {
writeDataError(writer, "exception " + e, s.getBytes(), blockCount);
continue;
}
}
writer.println("-- [" + i + "] child: " + children[i] + " pos: " + pos + " data: " + data);
}
......@@ -1084,8 +1090,7 @@ public class Recover extends Tool implements DataHandler {
return free;
}
private void dumpPageBtreeLeaf(PrintWriter writer, DataPage s) {
int entryCount = s.readShortInt();
private void dumpPageBtreeLeaf(PrintWriter writer, DataPage s, int entryCount, boolean positionOnly) {
int[] offsets = new int[entryCount];
for (int i = 0; i < entryCount; i++) {
offsets[i] = s.readShortInt();
......@@ -1095,11 +1100,15 @@ public class Recover extends Tool implements DataHandler {
s.setPos(off);
int pos = s.readInt();
Value data;
try {
data = s.readValue();
} catch (Throwable e) {
writeDataError(writer, "exception " + e, s.getBytes(), blockCount);
continue;
if (positionOnly) {
data = ValueInt.get(pos);
} else {
try {
data = s.readValue();
} catch (Throwable e) {
writeDataError(writer, "exception " + e, s.getBytes(), blockCount);
continue;
}
}
writer.println("-- [" + i + "] pos: " + pos + " data: " + data);
}
......
......@@ -7,13 +7,11 @@
package org.h2.test.synth;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Random;
import org.h2.test.TestBase;
import org.h2.tools.DeleteDbFiles;
......@@ -92,7 +90,7 @@ public class TestBtreeIndex extends TestBase {
}
String prefix = buff.toString();
DeleteDbFiles.execute(baseDir, null, true);
Connection conn = DriverManager.getConnection("jdbc:h2:" + baseDir + "/index", "sa", "sa");
Connection conn = getConnection("index");
Statement stat = conn.createStatement();
stat.execute("CREATE TABLE a(text VARCHAR PRIMARY KEY)");
PreparedStatement prepInsert = conn.prepareStatement("INSERT INTO a VALUES(?)");
......@@ -119,8 +117,7 @@ public class TestBtreeIndex extends TestBase {
prepDeleteAllButOne.setString(1, prefix + y);
int deleted = prepDeleteAllButOne.executeUpdate();
if (deleted < count - 1) {
System.out.println("ERROR deleted:" + deleted);
System.out.println("new TestBtreeIndex().");
printError(seed, "deleted:" + deleted);
}
count -= deleted;
} catch (SQLException e) {
......@@ -132,8 +129,7 @@ public class TestBtreeIndex extends TestBase {
prepDelete.setString(1, prefix + y);
int deleted = prepDelete.executeUpdate();
if (deleted > 1) {
System.out.println("ERROR deleted:" + deleted);
System.out.println("seed: " + seed);
printError(seed, "deleted:" + deleted);
}
count -= deleted;
} catch (SQLException e) {
......@@ -143,21 +139,33 @@ public class TestBtreeIndex extends TestBase {
}
}
}
ResultSet rs = conn.createStatement().executeQuery("SELECT text FROM a ORDER BY text");
int testCount = 0;
while (rs.next()) {
int testCount;
testCount = 0;
ResultSet rs = stat.executeQuery("SELECT text FROM a ORDER BY text");
ResultSet rs2 = conn.createStatement().executeQuery("SELECT text FROM a ORDER BY 'x' || text");
testCount = 0;
while (rs.next() && rs2.next()) {
if (!rs.getString(1).equals(rs2.getString(1))) {
fail("" + testCount);
}
testCount++;
}
assertFalse(rs.next());
assertFalse(rs2.next());
if (testCount != count) {
System.out.println("ERROR count:" + count + " testCount:" + testCount);
System.out.println("seed: " + seed);
printError(seed, "count:" + count + " testCount:" + testCount);
}
rs = conn.createStatement().executeQuery("SELECT text, count(*) FROM a GROUP BY text HAVING COUNT(*)>1");
rs = stat.executeQuery("SELECT text, count(*) FROM a GROUP BY text HAVING COUNT(*)>1");
if (rs.next()) {
System.out.println("ERROR");
System.out.println("seed: " + seed);
printError(seed, "testCount:" + testCount);
}
conn.close();
}
private void printError(int seed, String message) {
TestBase.logError("new TestBtreeIndex().init(test).testCase(" +
seed + "); // " + message, null);
fail(message);
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论