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

A persistent multi-version map (work in progress)

上级 2d531580
...@@ -108,11 +108,12 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> { ...@@ -108,11 +108,12 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
Page c2 = remove(c, writeVersion, key); Page c2 = remove(c, writeVersion, key);
if (c2 == null) { if (c2 == null) {
// this child was deleted // this child was deleted
p.remove(i); if (p.getKeyCount() == 1) {
if (p.getKeyCount() == 0) {
removePage(p); removePage(p);
return null; return null;
} }
p = p.copyOnWrite(writeVersion);
p.remove(i);
} else if (oldSize != c2.getTotalSize()) { } else if (oldSize != c2.getTotalSize()) {
p = p.copyOnWrite(writeVersion); p = p.copyOnWrite(writeVersion);
Object oldBounds = p.getKey(i); Object oldBounds = p.getKey(i);
...@@ -259,16 +260,11 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> { ...@@ -259,16 +260,11 @@ public class RtreeMap<K, V> extends BtreeMap<K, V> {
} }
private Page split(Page p, long writeVersion) { private Page split(Page p, long writeVersion) {
// if (p.getTotalSize() > 10000) { return quadraticSplit ?
// return
// }
return quadraticSplit | p.getTotalSize() > 10000 ?
splitQuadratic(p, writeVersion) : splitQuadratic(p, writeVersion) :
splitLinear(p, writeVersion); splitLinear(p, writeVersion);
} }
public static int splitLin, splitQuad;
private Page splitLinear(Page p, long writeVersion) { private Page splitLinear(Page p, long writeVersion) {
ArrayList<Object> keys = New.arrayList(); ArrayList<Object> keys = New.arrayList();
for (int i = 0; i < p.getKeyCount(); i++) { for (int i = 0; i < p.getKeyCount(); i++) {
...@@ -276,10 +272,8 @@ public static int splitLin, splitQuad; ...@@ -276,10 +272,8 @@ public static int splitLin, splitQuad;
} }
int[] extremes = keyType.getExtremes(keys); int[] extremes = keyType.getExtremes(keys);
if (extremes == null) { if (extremes == null) {
splitQuad++;
return splitQuadratic(p, writeVersion); return splitQuadratic(p, writeVersion);
} }
splitLin++;
Page splitA = newPage(p.isLeaf(), writeVersion); Page splitA = newPage(p.isLeaf(), writeVersion);
Page splitB = newPage(p.isLeaf(), writeVersion); Page splitB = newPage(p.isLeaf(), writeVersion);
move(p, splitA, extremes[0]); move(p, splitA, extremes[0]);
......
...@@ -27,7 +27,6 @@ import org.h2.jaqu.bytecode.Null; ...@@ -27,7 +27,6 @@ import org.h2.jaqu.bytecode.Null;
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;
import org.h2.util.Profiler;
/** /**
* Tests the tree map store. * Tests the tree map store.
...@@ -44,14 +43,7 @@ public class TestBtreeMapStore extends TestBase { ...@@ -44,14 +43,7 @@ public class TestBtreeMapStore extends TestBase {
} }
public void test() { public void test() {
// testRtreeMany(); testRtreeMany();
// System.out.println("lin: " + RtreeMap.splitLin + " quad:" + RtreeMap.splitQuad);
// testRtreeMany();
// System.out.println("lin: " + RtreeMap.splitLin + " quad:" + RtreeMap.splitQuad);
// testRtreeMany();
// System.out.println("lin: " + RtreeMap.splitLin + " quad:" + RtreeMap.splitQuad);
// if(true) return;
//
testRtree(); testRtree();
testRandomRtree(); testRandomRtree();
testCustomMapType(); testCustomMapType();
...@@ -71,78 +63,37 @@ public class TestBtreeMapStore extends TestBase { ...@@ -71,78 +63,37 @@ public class TestBtreeMapStore extends TestBase {
} }
private void testRtreeMany() { private void testRtreeMany() {
// quadratic:
// add: 796
// query: 161
// remove: 194
// linear: 50
// add: 345
// query: 244
// remove: 259
// MyTest
// add:197
// query:236
// delete:669
String fileName = getBaseDir() + "/testMeta.h3"; String fileName = getBaseDir() + "/testMeta.h3";
FileUtils.delete(fileName); FileUtils.delete(fileName);
BtreeMapStore s; BtreeMapStore s;
s = openStore(fileName); s = openStore(fileName);
s.setMaxPageSize(50); // s.setMaxPageSize(50);
RtreeMap<SpatialKey, String> r = s.openMap("data", "r", "s2", ""); RtreeMap<SpatialKey, String> r = s.openMap("data", "r", "s2", "");
// r.setQuadraticSplit(true); // r.setQuadraticSplit(true);
Random rand = new Random(1); Random rand = new Random(1);
int len = 1000000; int len = 1000;
// long t = System.currentTimeMillis();
long t = System.currentTimeMillis(); // Profiler prof = new Profiler();
// prof.startCollecting();
Profiler prof = new Profiler();
//prof.startCollecting();
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
float x = rand.nextFloat(), y = rand.nextFloat(); float x = rand.nextFloat(), y = rand.nextFloat();
float p = (float) (rand.nextFloat() * 0.000001); float p = (float) (rand.nextFloat() * 0.000001);
SpatialKey k = new SpatialKey(i, x - p, x + p, y - p, y + p); SpatialKey k = new SpatialKey(i, x - p, x + p, y - p, y + p);
r.add(k, "" + i); r.add(k, "" + i);
if (i > 0 && (i % 10000) == 0) { if (i > 0 && (i % len / 10) == 0) {
s.store(); s.store();
System.out.println("store " + i);
} }
// if (i > 0 && (i % 10000) == 0) { if (i > 0 && (i % 10000) == 0) {
// render(r, getBaseDir() + "/test.png"); render(r, getBaseDir() + "/test.png");
// } }
} }
//System.out.println(prof.getTop(5)); // System.out.println(prof.getTop(5));
// System.out.println("add: " + (System.currentTimeMillis() - t));
// quadratic
// add: 77967
// query: 39521
// remove: 22292
// linear
// add: 46136
// query: 65454
// remove: 35514
// > 10000 quadratic
// add: 54660
// query: 62946
System.out.println("add: " + (System.currentTimeMillis() - t));
s.store(); s.store();
s.close(); s.close();
s = openStore(fileName); s = openStore(fileName);
r = s.openMap("data", "r", "s2", ""); r = s.openMap("data", "r", "s2", "");
// t = System.currentTimeMillis();
t = System.currentTimeMillis();
rand = new Random(1); rand = new Random(1);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
float x = rand.nextFloat(), y = rand.nextFloat(); float x = rand.nextFloat(), y = rand.nextFloat();
...@@ -150,9 +101,7 @@ t = System.currentTimeMillis(); ...@@ -150,9 +101,7 @@ t = System.currentTimeMillis();
SpatialKey k = new SpatialKey(i, x - p, x + p, y - p, y + p); SpatialKey k = new SpatialKey(i, x - p, x + p, y - p, y + p);
assertEquals("" + i, r.get(k)); assertEquals("" + i, r.get(k));
} }
System.out.println("query: " + (System.currentTimeMillis() - t)); // System.out.println("query: " + (System.currentTimeMillis() - t));
assertEquals(len, r.size()); assertEquals(len, r.size());
int count = 0; int count = 0;
for (SpatialKey k : r.keySet()) { for (SpatialKey k : r.keySet()) {
...@@ -160,11 +109,9 @@ System.out.println("query: " + (System.currentTimeMillis() - t)); ...@@ -160,11 +109,9 @@ System.out.println("query: " + (System.currentTimeMillis() - t));
count++; count++;
} }
assertEquals(len, count); assertEquals(len, count);
// t = System.currentTimeMillis();
t = System.currentTimeMillis(); // Profiler prof = new Profiler();
// prof.startCollecting();
//Profiler prof = new Profiler();
//prof.startCollecting();
rand = new Random(1); rand = new Random(1);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
float x = rand.nextFloat(), y = rand.nextFloat(); float x = rand.nextFloat(), y = rand.nextFloat();
...@@ -173,11 +120,9 @@ t = System.currentTimeMillis(); ...@@ -173,11 +120,9 @@ t = System.currentTimeMillis();
r.remove(k); r.remove(k);
} }
assertEquals(0, r.size()); assertEquals(0, r.size());
s.close();
// System.out.println(prof.getTop(5)); // System.out.println(prof.getTop(5));
System.out.println("remove: " + (System.currentTimeMillis() - t)); // System.out.println("remove: " + (System.currentTimeMillis() - t));
} }
private void testRtree() { private void testRtree() {
...@@ -264,6 +209,7 @@ System.out.println("remove: " + (System.currentTimeMillis() - t)); ...@@ -264,6 +209,7 @@ System.out.println("remove: " + (System.currentTimeMillis() - t));
private static int[] scale(SpatialKey b, SpatialKey x, int width, int height) { private static int[] scale(SpatialKey b, SpatialKey x, int width, int height) {
int[] rect = { int[] rect = {
(int) ((x.min(0) - b.min(0)) * (width * 0.9) / (b.max(0) - b.min(0)) + width * 0.05),
(int) ((x.min(1) - b.min(1)) * (height * 0.9) / (b.max(1) - b.min(1)) + height * 0.05), (int) ((x.min(1) - b.min(1)) * (height * 0.9) / (b.max(1) - b.min(1)) + height * 0.05),
(int) ((x.max(0) - b.min(0)) * (width * 0.9) / (b.max(0) - b.min(0)) + width * 0.05), (int) ((x.max(0) - b.min(0)) * (width * 0.9) / (b.max(0) - b.min(0)) + width * 0.05),
(int) ((x.max(1) - b.min(1)) * (height * 0.9) / (b.max(1) - b.min(1)) + height * 0.05), (int) ((x.max(1) - b.min(1)) * (height * 0.9) / (b.max(1) - b.min(1)) + height * 0.05),
......
...@@ -357,12 +357,12 @@ public class BtreeMap<K, V> { ...@@ -357,12 +357,12 @@ public class BtreeMap<K, V> {
Page c2 = remove(c, writeVersion, key); Page c2 = remove(c, writeVersion, key);
if (c2 == null) { if (c2 == null) {
// this child was deleted // this child was deleted
p = p.copyOnWrite(writeVersion); if (p.getKeyCount() == 1) {
p.remove(index);
if (p.getKeyCount() == 0) {
removePage(p); removePage(p);
p = p.getChildPage(0); p = p.getChildPage(0);
} }
p = p.copyOnWrite(writeVersion);
p.remove(index);
} else if (oldSize != c2.getTotalSize()) { } else if (oldSize != c2.getTotalSize()) {
p = p.copyOnWrite(writeVersion); p = p.copyOnWrite(writeVersion);
p.setChild(index, c2); p.setChild(index, c2);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论