mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8281631: HashMap copy constructor and putAll can over-allocate table
Reviewed-by: smarks
This commit is contained in:
parent
0cf291bc31
commit
3e393047e1
4 changed files with 265 additions and 79 deletions
|
@ -495,9 +495,9 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
int s = m.size();
|
||||
if (s > 0) {
|
||||
if (table == null) { // pre-size
|
||||
float ft = ((float)s / loadFactor) + 1.0F;
|
||||
int t = ((ft < (float)MAXIMUM_CAPACITY) ?
|
||||
(int)ft : MAXIMUM_CAPACITY);
|
||||
double dt = Math.ceil(s / (double)loadFactor);
|
||||
int t = ((dt < (double)MAXIMUM_CAPACITY) ?
|
||||
(int)dt : MAXIMUM_CAPACITY);
|
||||
if (t > threshold)
|
||||
threshold = tableSizeFor(t);
|
||||
} else {
|
||||
|
@ -1527,12 +1527,12 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
|||
} else if (mappings == 0) {
|
||||
// use defaults
|
||||
} else if (mappings > 0) {
|
||||
float fc = (float)mappings / lf + 1.0f;
|
||||
int cap = ((fc < DEFAULT_INITIAL_CAPACITY) ?
|
||||
double dc = Math.ceil(mappings / (double)lf);
|
||||
int cap = ((dc < DEFAULT_INITIAL_CAPACITY) ?
|
||||
DEFAULT_INITIAL_CAPACITY :
|
||||
(fc >= MAXIMUM_CAPACITY) ?
|
||||
(dc >= MAXIMUM_CAPACITY) ?
|
||||
MAXIMUM_CAPACITY :
|
||||
tableSizeFor((int)fc));
|
||||
tableSizeFor((int)dc));
|
||||
float ft = (float)cap * lf;
|
||||
threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
|
||||
(int)ft : Integer.MAX_VALUE);
|
||||
|
|
|
@ -213,9 +213,7 @@ public class WeakHashMap<K,V>
|
|||
if (loadFactor <= 0 || Float.isNaN(loadFactor))
|
||||
throw new IllegalArgumentException("Illegal Load factor: "+
|
||||
loadFactor);
|
||||
int capacity = 1;
|
||||
while (capacity < initialCapacity)
|
||||
capacity <<= 1;
|
||||
int capacity = HashMap.tableSizeFor(initialCapacity);
|
||||
table = newTable(capacity);
|
||||
this.loadFactor = loadFactor;
|
||||
threshold = (int)(capacity * loadFactor);
|
||||
|
@ -251,7 +249,7 @@ public class WeakHashMap<K,V>
|
|||
* @since 1.3
|
||||
*/
|
||||
public WeakHashMap(Map<? extends K, ? extends V> m) {
|
||||
this(Math.max((int) ((float)m.size() / DEFAULT_LOAD_FACTOR + 1.0F),
|
||||
this(Math.max((int) Math.ceil(m.size() / (double)DEFAULT_LOAD_FACTOR),
|
||||
DEFAULT_INITIAL_CAPACITY),
|
||||
DEFAULT_LOAD_FACTOR);
|
||||
putAll(m);
|
||||
|
@ -468,7 +466,7 @@ public class WeakHashMap<K,V>
|
|||
modCount++;
|
||||
Entry<K,V> e = tab[i];
|
||||
tab[i] = new Entry<>(k, value, queue, h, e);
|
||||
if (++size >= threshold)
|
||||
if (++size > threshold)
|
||||
resize(tab.length * 2);
|
||||
return null;
|
||||
}
|
||||
|
@ -557,7 +555,7 @@ public class WeakHashMap<K,V>
|
|||
* to at most one extra resize.
|
||||
*/
|
||||
if (numKeysToBeAdded > threshold) {
|
||||
int targetCapacity = (int)(numKeysToBeAdded / loadFactor + 1);
|
||||
int targetCapacity = (int)Math.ceil(numKeysToBeAdded / (double)loadFactor);
|
||||
if (targetCapacity > MAXIMUM_CAPACITY)
|
||||
targetCapacity = MAXIMUM_CAPACITY;
|
||||
int newCapacity = table.length;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue