提交 0c05828b authored 作者: noelgrandin@gmail.com's avatar noelgrandin@gmail.com

Fix bug which could generate a NegativeArraySizeException when performing large…

Fix bug which could generate a NegativeArraySizeException when performing large (>40M) row union operations (v2)
上级 bbc36837
......@@ -11,7 +11,8 @@ package org.h2.util;
*/
public abstract class HashBase {
private static final int MAX_LOAD = 90;
/** declared as long so we do long arithmetic so we don't overflow */
private static final long MAX_LOAD = 90;
/**
* The bit mask to get the index from the hash code.
......@@ -98,14 +99,14 @@ public abstract class HashBase {
protected void reset(int newLevel) {
// can't exceed 30 or we will generate a negative value for the "len" field
if (newLevel > 30) {
newLevel = 30;
throw new IllegalStateException("exceeded max size of hash table");
}
minSize = size * 3 / 4;
size = 0;
level = newLevel;
len = 2 << level;
mask = len - 1;
maxSize = (int) (len * MAX_LOAD / 100L);
maxSize = (int) (len * MAX_LOAD / 100);
deletedCount = 0;
maxDeleted = 20 + len / 2;
}
......
......@@ -45,6 +45,10 @@ public class IntIntHashMap extends HashBase {
return;
}
checkSizePut();
internalPut(key, value);
}
private void internalPut(int key, int value) {
int index = getIndex(key);
int plus = 1;
int deleted = -1;
......@@ -116,7 +120,8 @@ public class IntIntHashMap extends HashBase {
for (int i = 0; i < oldKeys.length; i++) {
int k = oldKeys[i];
if (k != 0) {
put(k, oldValues[i]);
// skip the checkSizePut so we don't end up accidentally recursing
internalPut(k, oldValues[i]);
}
}
}
......
......@@ -46,7 +46,8 @@ public class ValueHashMap<V> extends HashBase {
for (int i = 0; i < len; i++) {
Value k = oldKeys[i];
if (k != null && k != ValueNull.DELETED) {
put(k, oldValues[i]);
// skip the checkSizePut so we don't end up accidentally recursing
internalPut(k, oldValues[i]);
}
}
}
......@@ -63,6 +64,10 @@ public class ValueHashMap<V> extends HashBase {
*/
public void put(Value key, V value) {
checkSizePut();
internalPut(key, value);
}
private void internalPut(Value key, V value) {
int index = getIndex(key);
int plus = 1;
int deleted = -1;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论