Unverified 提交 11f00203 authored 作者: Andrei Tokar's avatar Andrei Tokar 提交者: GitHub

Merge pull request #1717 from h2database/issue-1592_invalid_tree

Backward compatibility patch for #1952
...@@ -154,7 +154,6 @@ public class Cursor<K, V> implements Iterator<K> { ...@@ -154,7 +154,6 @@ public class Cursor<K, V> implements Iterator<K> {
private static CursorPos traverseDown(Page p, Object key) { private static CursorPos traverseDown(Page p, Object key) {
CursorPos cursorPos = null; CursorPos cursorPos = null;
while (!p.isLeaf()) { while (!p.isLeaf()) {
assert p.getKeyCount() > 0;
int index = 0; int index = 0;
if(key != null) { if(key != null) {
index = p.binarySearch(key) + 1; index = p.binarySearch(key) + 1;
......
...@@ -294,7 +294,7 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -294,7 +294,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private K getFirstLast(boolean first) { private K getFirstLast(boolean first) {
Page p = getRootPage(); Page p = getRootPage();
if (p.getKeyCount() == 0) { if (p.getTotalCount() == 0) {
return null; return null;
} }
while (true) { while (true) {
...@@ -1305,10 +1305,15 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -1305,10 +1305,15 @@ public class MVMap<K, V> extends AbstractMap<K, V>
private static Page replacePage(CursorPos path, Page replacement, IntValueHolder unsavedMemoryHolder) { private static Page replacePage(CursorPos path, Page replacement, IntValueHolder unsavedMemoryHolder) {
int unsavedMemory = replacement.getMemory(); int unsavedMemory = replacement.getMemory();
while (path != null) { while (path != null) {
Page parent = path.page;
// condition below sould always be true, but older versions (up to 1.4.197)
// may create single-childed (with no keys) internal nodes, which we skip here
if (parent.getKeyCount() > 0) {
Page child = replacement; Page child = replacement;
replacement = path.page.copy(); replacement = parent.copy();
replacement.setChild(path.index, child); replacement.setChild(path.index, child);
unsavedMemory += replacement.getMemory(); unsavedMemory += replacement.getMemory();
}
path = path.parent; path = path.parent;
} }
unsavedMemoryHolder.value += unsavedMemory; unsavedMemoryHolder.value += unsavedMemory;
...@@ -1706,15 +1711,27 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -1706,15 +1711,27 @@ public class MVMap<K, V> extends AbstractMap<K, V>
} }
if (p.getTotalCount() == 1 && pos != null) { if (p.getTotalCount() == 1 && pos != null) {
int keyCount;
do {
p = pos.page; p = pos.page;
index = pos.index; index = pos.index;
pos = pos.parent; pos = pos.parent;
if (p.getKeyCount() == 1) { keyCount = p.getKeyCount();
// condition below sould always be false, but older versions (up to 1.4.197)
// may create single-childed (with no keys) internal nodes, which we skip here
} while (keyCount == 0 && pos != null);
if (keyCount <= 1) {
if (keyCount == 1) {
assert index <= 1; assert index <= 1;
p = p.getChildPage(1 - index); p = p.getChildPage(1 - index);
} else {
// if root happens to be such single-childed (with no keys) internal node,
// then just replace it with empty leaf
p = Page.createEmptyLeaf(this);
}
break; break;
} }
assert p.getKeyCount() > 1;
} }
p = p.copy(); p = p.copy();
p.remove(index); p.remove(index);
...@@ -1864,7 +1881,6 @@ public class MVMap<K, V> extends AbstractMap<K, V> ...@@ -1864,7 +1881,6 @@ public class MVMap<K, V> extends AbstractMap<K, V>
private static CursorPos traverseDown(Page p, Object key) { private static CursorPos traverseDown(Page p, Object key) {
CursorPos pos = null; CursorPos pos = null;
while (!p.isLeaf()) { while (!p.isLeaf()) {
assert p.getKeyCount() > 0;
int index = p.binarySearch(key) + 1; int index = p.binarySearch(key) + 1;
if (index < 0) { if (index < 0) {
index = -index; index = -index;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论