提交 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>
}
return (K) p.getKey((int) (index - offset));
}
int i = 0, size = p.getChildPageCount();
int i = 0, size = getChildPageCount(p);
for (; i < size; i++) {
long c = p.getCounts(i);
if (index < c + offset) {
......@@ -348,7 +348,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
if (p.isLeaf()) {
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>
x++;
}
while (true) {
if (x < 0 || x >= p.getChildPageCount()) {
if (x < 0 || x >= getChildPageCount(p)) {
return null;
}
K k = getMinMax(p.getChildPage(x), key, min, excluding);
......@@ -480,34 +480,6 @@ public class MVMap<K, V> extends AbstractMap<K, V>
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.
*
......@@ -846,7 +818,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
return 1;
}
int writtenPageCount = 0;
for (int i = 0; i < p.getChildPageCount(); i++) {
for (int i = 0; i < getChildPageCount(p); i++) {
long childPos = p.getChildPagePos(i);
if (childPos != 0 && DataUtils.getPageType(childPos) == DataUtils.PAGE_TYPE_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>
* @return the number of direct children
*/
protected int getChildPageCount(Page p) {
return p.getChildPageCount();
return p.getRawChildPageCount();
}
/**
......@@ -1314,12 +1286,13 @@ public class MVMap<K, V> extends AbstractMap<K, V>
}
} else {
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;
long p = source.getChildPagePos(i);
if (p != 0) {
// p == 0 means no child
// (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);
}
}
......
......@@ -617,7 +617,7 @@ public class Page {
*/
void removeAllRecursive() {
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];
if (ref.page != null) {
ref.page.removeAllRecursive();
......@@ -990,7 +990,7 @@ public class Page {
return version;
}
public int getChildPageCount() {
public int getRawChildPageCount() {
return childCount;
}
......@@ -1041,7 +1041,7 @@ public class Page {
mem += valueType.getMemory(values[i]);
}
} else {
mem += this.getChildPageCount() * DataUtils.PAGE_MEMORY_CHILD;
mem += this.getRawChildPageCount() * DataUtils.PAGE_MEMORY_CHILD;
}
addMemory(mem - memory);
}
......
......@@ -120,48 +120,6 @@ public class MVRTreeMap<V> extends MVMap<SpatialKey, V> {
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
protected Object remove(Page p, long writeVersion, Object key) {
Object result = null;
......@@ -508,7 +466,7 @@ public class MVRTreeMap<V> extends MVMap<SpatialKey, V> {
@Override
protected int getChildPageCount(Page p) {
return p.getChildPageCount() - 1;
return p.getRawChildPageCount() - 1;
}
/**
......
......@@ -87,6 +87,7 @@ public class TestSpatial extends TestBase {
testValueGeometryScript();
testInPlaceUpdate();
testScanIndexOnNonSpatialQuery();
testStoreCorruption();
}
private void testHashCode() {
......@@ -851,4 +852,31 @@ public class TestSpatial extends TestBase {
}
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论