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

MVStore: compacting a store with an R-tree did not always work.

上级 fbf19960
...@@ -249,7 +249,7 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -249,7 +249,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
} }
return (K) p.getKey((int) (index - offset)); return (K) p.getKey((int) (index - offset));
} }
int i = 0, size = p.getChildPageCount(); int i = 0, size = getChildPageCount(p);
for (; i < size; i++) { for (; i < size; i++) {
long c = p.getCounts(i); long c = p.getCounts(i);
if (index < c + offset) { if (index < c + offset) {
...@@ -348,7 +348,7 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -348,7 +348,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
if (p.isLeaf()) { if (p.isLeaf()) {
return (K) p.getKey(first ? 0 : p.getKeyCount() - 1); return (K) p.getKey(first ? 0 : p.getKeyCount() - 1);
} }
p = p.getChildPage(first ? 0 : p.getChildPageCount() - 1); p = p.getChildPage(first ? 0 : getChildPageCount(p) - 1);
} }
} }
...@@ -427,7 +427,7 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -427,7 +427,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
x++; x++;
} }
while (true) { while (true) {
if (x < 0 || x >= p.getChildPageCount()) { if (x < 0 || x >= getChildPageCount(p)) {
return null; return null;
} }
K k = getMinMax(p.getChildPage(x), key, min, excluding); K k = getMinMax(p.getChildPage(x), key, min, excluding);
...@@ -480,34 +480,6 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -480,34 +480,6 @@ public class MVMap<K, V> extends AbstractMap<K, V>
return get(key) != null; return get(key) != null;
} }
/**
* Get a key that is referenced in the given page or a child page.
*
* @param p the page
* @return the key, or null if not found
*/
protected K getLiveKey(Page p) {
while (!p.isLeaf()) {
p = p.getLiveChildPage(0);
if (p == null) {
return null;
}
}
@SuppressWarnings("unchecked")
K key = (K) p.getKey(0);
Page p2 = binarySearchPage(root, key);
if (p2 == null) {
return null;
}
if (p2.getPos() == 0) {
return p2 == p ? key : null;
}
if (p2.getPos() == p.getPos()) {
return key;
}
return null;
}
/** /**
* Get the value for the given key, or null if not found. * Get the value for the given key, or null if not found.
* *
...@@ -846,7 +818,7 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -846,7 +818,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
return 1; return 1;
} }
int writtenPageCount = 0; int writtenPageCount = 0;
for (int i = 0; i < p.getChildPageCount(); i++) { for (int i = 0; i < getChildPageCount(p); i++) {
long childPos = p.getChildPagePos(i); long childPos = p.getChildPagePos(i);
if (childPos != 0 && DataUtils.getPageType(childPos) == DataUtils.PAGE_TYPE_LEAF) { if (childPos != 0 && DataUtils.getPageType(childPos) == DataUtils.PAGE_TYPE_LEAF) {
// we would need to load the page, and it's a leaf: // we would need to load the page, and it's a leaf:
...@@ -1250,7 +1222,7 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -1250,7 +1222,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
* @return the number of direct children * @return the number of direct children
*/ */
protected int getChildPageCount(Page p) { protected int getChildPageCount(Page p) {
return p.getChildPageCount(); return p.getRawChildPageCount();
} }
/** /**
...@@ -1314,12 +1286,13 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -1314,12 +1286,13 @@ public class MVMap<K, V> extends AbstractMap<K, V>
} }
} else { } else {
CursorPos pos = new CursorPos(target, 0, parent); CursorPos pos = new CursorPos(target, 0, parent);
for (int i = 0; i < target.getChildPageCount(); i++) { for (int i = 0; i < getChildPageCount(target); i++) {
pos.index = i; pos.index = i;
long p = source.getChildPagePos(i); long p = source.getChildPagePos(i);
if (p != 0) { if (p != 0) {
// p == 0 means no child // p == 0 means no child
// (for example the last entry of an r-tree node) // (for example the last entry of an r-tree node)
// (the MVMap is also used for r-trees for compacting)
copy(source.getChildPage(i), pos); copy(source.getChildPage(i), pos);
} }
} }
......
...@@ -617,7 +617,7 @@ public class Page { ...@@ -617,7 +617,7 @@ public class Page {
*/ */
void removeAllRecursive() { void removeAllRecursive() {
if (children != null) { if (children != null) {
for (int i = 0, size = childCount; i < size; i++) { for (int i = 0, size = map.getChildPageCount(this); i < size; i++) {
PageReference ref = children[i]; PageReference ref = children[i];
if (ref.page != null) { if (ref.page != null) {
ref.page.removeAllRecursive(); ref.page.removeAllRecursive();
...@@ -990,7 +990,7 @@ public class Page { ...@@ -990,7 +990,7 @@ public class Page {
return version; return version;
} }
public int getChildPageCount() { public int getRawChildPageCount() {
return childCount; return childCount;
} }
...@@ -1041,7 +1041,7 @@ public class Page { ...@@ -1041,7 +1041,7 @@ public class Page {
mem += valueType.getMemory(values[i]); mem += valueType.getMemory(values[i]);
} }
} else { } else {
mem += this.getChildPageCount() * DataUtils.PAGE_MEMORY_CHILD; mem += this.getRawChildPageCount() * DataUtils.PAGE_MEMORY_CHILD;
} }
addMemory(mem - memory); addMemory(mem - memory);
} }
......
...@@ -120,48 +120,6 @@ public class MVRTreeMap<V> extends MVMap<SpatialKey, V> { ...@@ -120,48 +120,6 @@ public class MVRTreeMap<V> extends MVMap<SpatialKey, V> {
return null; return null;
} }
@Override
protected SpatialKey getLiveKey(Page p) {
while (!p.isLeaf()) {
p = p.getLiveChildPage(0);
if (p == null) {
return null;
}
}
SpatialKey key = (SpatialKey) p.getKey(0);
Page p2 = getPage(root, key);
if (p2 == null) {
return null;
}
if (p2.getPos() == 0) {
return p2 == p ? key : null;
}
if (p2.getPos() == p.getPos()) {
return key;
}
return null;
}
private Page getPage(Page p, Object key) {
if (!p.isLeaf()) {
for (int i = 0; i < p.getKeyCount(); i++) {
if (contains(p, i, key)) {
Page x = getPage(p.getChildPage(i), key);
if (x != null) {
return x;
}
}
}
} else {
for (int i = 0; i < p.getKeyCount(); i++) {
if (keyType.equals(p.getKey(i), key)) {
return p;
}
}
}
return null;
}
@Override @Override
protected Object remove(Page p, long writeVersion, Object key) { protected Object remove(Page p, long writeVersion, Object key) {
Object result = null; Object result = null;
...@@ -508,7 +466,7 @@ public class MVRTreeMap<V> extends MVMap<SpatialKey, V> { ...@@ -508,7 +466,7 @@ public class MVRTreeMap<V> extends MVMap<SpatialKey, V> {
@Override @Override
protected int getChildPageCount(Page p) { protected int getChildPageCount(Page p) {
return p.getChildPageCount() - 1; return p.getRawChildPageCount() - 1;
} }
/** /**
......
...@@ -87,6 +87,7 @@ public class TestSpatial extends TestBase { ...@@ -87,6 +87,7 @@ public class TestSpatial extends TestBase {
testValueGeometryScript(); testValueGeometryScript();
testInPlaceUpdate(); testInPlaceUpdate();
testScanIndexOnNonSpatialQuery(); testScanIndexOnNonSpatialQuery();
testStoreCorruption();
} }
private void testHashCode() { private void testHashCode() {
...@@ -851,4 +852,31 @@ public class TestSpatial extends TestBase { ...@@ -851,4 +852,31 @@ public class TestSpatial extends TestBase {
} }
deleteDb("spatial"); deleteDb("spatial");
} }
private void testStoreCorruption() throws SQLException {
deleteDb("spatial");
Connection conn = getConnection(url);
try {
Statement stat = conn.createStatement();
stat.execute("drop table if exists pt_cloud;\n" +
"CREATE TABLE PT_CLOUD AS SELECT CONCAT('POINT(',A.X,' ',B.X,')')::geometry the_geom from" +
" system_range(1e6,1e6+10) A,system_range(6e6,6e6+10) B;\n" +
"create spatial index ptindex on pt_cloud(the_geom);");
// Wait some time
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
throw new SQLException(ex);
}
stat.execute("drop table if exists pt_cloud;\n" +
"CREATE TABLE PT_CLOUD AS SELECT CONCAT('POINT(',A.X,' ',B.X,')')::geometry the_geom from" +
" system_range(1e6,1e6+50) A,system_range(6e6,6e6+50) B;\n" +
"create spatial index ptindex on pt_cloud(the_geom);\n" +
"shutdown compact;");
} finally {
// Close the database
conn.close();
}
deleteDb("spatial");
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论