提交 36415f3f authored 作者: Thomas Mueller's avatar Thomas Mueller

A persistent tree map (work in progress).

上级 582ca70b
......@@ -105,7 +105,7 @@ import org.h2.test.server.TestWeb;
import org.h2.test.server.TestInit;
import org.h2.test.store.TestCacheLIRS;
import org.h2.test.store.TestDataUtils;
import org.h2.test.store.TestTreeMapStore;
import org.h2.test.store.TestBtreeMapStore;
import org.h2.test.synth.TestBtreeIndex;
import org.h2.test.synth.TestCrashAPI;
import org.h2.test.synth.TestDiskFull;
......@@ -664,8 +664,8 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
private void testUnit() {
// store
new TestBtreeMapStore().runTest(this);
new TestCacheLIRS().runTest(this);
new TestTreeMapStore().runTest(this);
new TestDataUtils().runTest(this);
// unit
......
......@@ -17,7 +17,7 @@ import org.h2.test.TestBase;
/**
* Tests the tree map store.
*/
public class TestTreeMapStore extends TestBase {
public class TestBtreeMapStore extends TestBase {
/**
* Run just this test.
......@@ -28,7 +28,10 @@ public class TestTreeMapStore extends TestBase {
TestBase.createCaller().init().test();
}
public void test() throws Exception {
public void test() {
testRollbackInMemory();
testRollbackStored();
testMeta();
testLargeImport();
testBtreeStore();
testDefragment();
......@@ -39,9 +42,150 @@ public class TestTreeMapStore extends TestBase {
testSimple();
}
private void testLargeImport() throws Exception {
private void testRollbackStored() {
String fileName = getBaseDir() + "/testMeta.h3";
FileUtils.delete(fileName);
BtreeMap<String, String> meta;
BtreeMapStore s = openStore(fileName);
assertEquals(-1, s.getRetainChunk());
s.setRetainChunk(0);
assertEquals(0, s.getRetainChunk());
assertEquals(0, s.getCurrentVersion());
assertFalse(s.hasUnsavedChanges());
BtreeMap<String, String> m = s.openMap("data", String.class, String.class);
assertTrue(s.hasUnsavedChanges());
BtreeMap<String, String> m0 = s.openMap("data0", String.class, String.class);
m.put("1", "Hello");
assertEquals(1, s.commit());
s.rollbackTo(1);
assertEquals("Hello", m.get("1"));
long v2 = s.store();
assertFalse(s.hasUnsavedChanges());
s.close();
s = openStore(fileName);
s.setRetainChunk(0);
assertEquals(2, s.getCurrentVersion());
meta = s.getMetaMap();
m = s.openMap("data", String.class, String.class);
m0 = s.openMap("data0", String.class, String.class);
BtreeMap<String, String> m1 = s.openMap("data1", String.class, String.class);
m.put("1", "Hallo");
m0.put("1", "Hallo");
m1.put("1", "Hallo");
assertEquals("Hallo", m.get("1"));
assertEquals("Hallo", m1.get("1"));
s.rollbackTo(v2);
assertFalse(s.hasUnsavedChanges());
assertNull(meta.get("map.data1"));
assertNull(m0.get("1"));
assertEquals("Hello", m.get("1"));
s.store();
s.close();
s = openStore(fileName);
s.setRetainChunk(0);
assertEquals(2, s.getCurrentVersion());
meta = s.getMetaMap();
assertTrue(meta.get("map.data") != null);
assertTrue(meta.get("map.data0") != null);
assertNull(meta.get("map.data1"));
m = s.openMap("data", String.class, String.class);
m0 = s.openMap("data0", String.class, String.class);
assertNull(m0.get("1"));
assertEquals("Hello", m.get("1"));
assertFalse(m0.isReadOnly());
m.put("1", "Hallo");
s.commit();
assertEquals(3, s.getCurrentVersion());
long v4 = s.store();
assertEquals(4, v4);
assertEquals(4, s.getCurrentVersion());
s.close();
s = openStore(fileName);
s.setRetainChunk(0);
m = s.openMap("data", String.class, String.class);
m.put("1", "Hello");
s.store();
s.close();
s = openStore(fileName);
s.setRetainChunk(0);
m = s.openMap("data", String.class, String.class);
assertEquals("Hello", m.get("1"));
s.rollbackTo(v4);
assertEquals("Hallo", m.get("1"));
s.close();
s = openStore(fileName);
s.setRetainChunk(0);
m = s.openMap("data", String.class, String.class);
assertEquals("Hallo", m.get("1"));
s.close();
}
private void testRollbackInMemory() {
String fileName = getBaseDir() + "/testMeta.h3";
FileUtils.delete(fileName);
BtreeMapStore s = openStore(fileName);
s.setMaxPageSize(5);
BtreeMap<String, String> m = s.openMap("data", String.class, String.class);
BtreeMap<String, String> m0 = s.openMap("data0", String.class, String.class);
BtreeMap<String, String> m2 = s.openMap("data2", String.class, String.class);
m.put("1", "Hello");
for (int i = 0; i < 10; i++) {
m2.put("" + i, "Test");
}
long v1 = s.commit();
assertEquals(1, v1);
BtreeMap<String, String> m1 = s.openMap("data1", String.class, String.class);
assertEquals("Test", m2.get("1"));
m.put("1", "Hallo");
m0.put("1", "Hallo");
m1.put("1", "Hallo");
m2.clear();
assertEquals("Hallo", m.get("1"));
assertEquals("Hallo", m1.get("1"));
s.rollbackTo(v1);
for (int i = 0; i < 10; i++) {
assertEquals("Test", m2.get("" + i));
}
assertEquals("Hello", m.get("1"));
assertNull(m0.get("1"));
assertTrue(m1.isClosed());
assertFalse(m0.isReadOnly());
assertTrue(m1.isReadOnly());
s.close();
}
private void testMeta() {
String fileName = getBaseDir() + "/testMeta.h3";
FileUtils.delete(fileName);
BtreeMapStore s = openStore(fileName);
BtreeMap<String, String> m = s.getMetaMap();
s.setRetainChunk(0);
BtreeMap<String, String> data = s.openMap("data", String.class, String.class);
data.put("1", "Hello");
data.put("2", "World");
s.store();
assertEquals("1/0//", m.get("map.data"));
assertTrue(m.containsKey("chunk.1"));
data.put("1", "Hallo");
s.store();
assertEquals("1/0//", m.get("map.data"));
assertTrue(m.get("root.1").length() > 0);
assertTrue(m.containsKey("chunk.1"));
assertTrue(m.containsKey("chunk.2"));
s.rollbackTo(1);
assertTrue(m.containsKey("chunk.1"));
assertFalse(m.containsKey("chunk.2"));
s.close();
}
private void testLargeImport() {
String fileName = getBaseDir() + "/testCsv.h3";
int len = 10000;
int len = 1000;
for (int j = 0; j < 5; j++) {
FileUtils.delete(fileName);
BtreeMapStore s = openStore(fileName);
......@@ -188,7 +332,7 @@ public class TestTreeMapStore extends TestBase {
BtreeMap<Integer, Integer> m = s.openMap("data", Integer.class, Integer.class);
TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
Random r = new Random(1);
int operationCount = 10000;
int operationCount = 1000;
int maxValue = 30;
for (int i = 0; i < operationCount; i++) {
int k = r.nextInt(maxValue);
......
......@@ -5,7 +5,7 @@
*/
package org.h2.test.store;
import org.h2.dev.store.btree.Page;
import org.h2.dev.store.btree.DataUtils;
import org.h2.test.TestBase;
/**
......@@ -23,30 +23,59 @@ public class TestDataUtils extends TestBase {
}
public void test() throws Exception {
testCheckValue();
testPagePos();
testEncodeLength();
}
private void testCheckValue() {
// 0 xor 0 = 0
assertEquals(0, DataUtils.getCheckValue(0));
// 1111... xor 1111... = 0
assertEquals(0, DataUtils.getCheckValue(-1));
// 0 xor 1111... = 1111...
assertEquals((short) -1, DataUtils.getCheckValue(-1 >>> 16));
// 1111... xor 0 = 1111...
assertEquals((short) -1, DataUtils.getCheckValue(-1 << 16));
// 0 xor 1000... = 1000...
assertEquals((short) (1 << 15), DataUtils.getCheckValue(1 << 15));
// 1000... xor 0 = 1000...
assertEquals((short) (1 << 15), DataUtils.getCheckValue(1 << 31));
}
private void testPagePos() {
for (int chunkId = 0; chunkId < 67000000; chunkId += 670000) {
for (long offset = 0; offset < Integer.MAX_VALUE; offset += Integer.MAX_VALUE / 100) {
for (int length = 0; length < 2000000; length += 200000) {
long pos = DataUtils.getPos(chunkId, (int) offset, length);
assertEquals(chunkId, DataUtils.getChunkId(pos));
assertEquals(offset, DataUtils.getOffset(pos));
assertTrue(DataUtils.getMaxLength(pos) >= length);
}
}
}
}
private void testEncodeLength() {
int lastCode = 0;
assertEquals(0, Page.encodeLength(32));
assertEquals(1, Page.encodeLength(33));
assertEquals(1, Page.encodeLength(48));
assertEquals(2, Page.encodeLength(49));
assertEquals(30, Page.encodeLength(1024 * 1024));
assertEquals(31, Page.encodeLength(1024 * 1024 + 1));
assertEquals(0, DataUtils.encodeLength(32));
assertEquals(1, DataUtils.encodeLength(33));
assertEquals(1, DataUtils.encodeLength(48));
assertEquals(2, DataUtils.encodeLength(49));
assertEquals(30, DataUtils.encodeLength(1024 * 1024));
assertEquals(31, DataUtils.encodeLength(1024 * 1024 + 1));
for (int i = 1024 * 1024 + 1; i < 100 * 1024 * 1024; i += 1024) {
int code = Page.encodeLength(i);
int code = DataUtils.encodeLength(i);
assertEquals(31, code);
}
for (int i = 0; i < 1024 * 1024; i++) {
int code = Page.encodeLength(i);
for (int i = 0; i < 2 * 1024 * 1024; i++) {
int code = DataUtils.encodeLength(i);
assertTrue(code <= 31 && code >= 0);
assertTrue(code >= lastCode);
if (code > lastCode) {
lastCode = code;
}
int max = Page.getMaxLength(code);
int max = DataUtils.getMaxLength(code);
assertTrue(max >= i && max >= 32);
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论