RFR: [6904367]: (coll) IdentityHashMap is resized before exceeding the expected maximum size
Peter Levart
peter.levart at gmail.com
Tue Jul 8 10:41:37 UTC 2014
On 07/08/2014 12:12 PM, Peter Levart wrote:
> On 07/08/2014 09:33 AM, Martin Buchholz wrote:
>> I've updated the webrev
>> http://cr.openjdk.java.net/~martin/webrevs/openjdk9/IdentityHashMap-capacity/
>>
>> It now has all my TODOs done.
>> The test case has been testng-ified.
>
> Hi Martin,
>
> What happened to the desire that when OOME is thrown on resizing, IHM
> is left unchanged?
>
> Regards, Peter
Hi Martin,
I took your latest version of the patch and modified it a little:
http://cr.openjdk.java.net/~plevart/jdk9-dev/IdentityHashMap/webrev.01/
Here's a diff to your version:
*** src/share/classes/java/util/IdentityHashMap.java.mb 2014-07-08
12:37:57.267916926 +0200
--- src/share/classes/java/util/IdentityHashMap.java 2014-07-08
12:34:25.739767669 +0200
***************
*** 437,449 ****
if (size == MAXIMUM_CAPACITY - 1)
throw new IllegalStateException("Capacity exhausted.");
! modCount++;
! tab[i] = k;
! tab[i + 1] = value;
! size++;
! int x = size + (size << 1); // Optimized form of 3 * size
! if (x > len)
! resize(len); // len == 2 * current capacity.
return null;
}
--- 437,457 ----
if (size == MAXIMUM_CAPACITY - 1)
throw new IllegalStateException("Capacity exhausted.");
!
! int x = size + (size << 1) + 3; // Optimized form of 3 * (size
+ 1)
! if (x > len) {
! if (resize(len)) { // len == 2 * current capacity.
! tab = table;
! len = tab.length;
! i = hash(key, len);
! while (tab[i] != null)
! i = nextKeyIndex(i, len);
! }
! modCount++;
! tab[i] = k;
! tab[i + 1] = value;
! size++;
! }
return null;
}
***************
*** 452,468 ****
*
* @param newCapacity the new capacity, must be a power of two.
*/
! private void resize(int newCapacity) {
// assert (newCapacity & -newCapacity) == newCapacity; //
power of 2
int newLength = newCapacity * 2;
Object[] oldTable = table;
int oldLength = oldTable.length;
if (oldLength == 2 * MAXIMUM_CAPACITY) { // can't expand any
further
! return;
}
if (oldLength >= newLength)
! return;
Object[] newTable = new Object[newLength];
--- 460,476 ----
*
* @param newCapacity the new capacity, must be a power of two.
*/
! private boolean resize(int newCapacity) {
// assert (newCapacity & -newCapacity) == newCapacity; //
power of 2
int newLength = newCapacity * 2;
Object[] oldTable = table;
int oldLength = oldTable.length;
if (oldLength == 2 * MAXIMUM_CAPACITY) { // can't expand any
further
! return false;
}
if (oldLength >= newLength)
! return false;
Object[] newTable = new Object[newLength];
***************
*** 480,485 ****
--- 488,494 ----
}
}
table = newTable;
+ return true;
}
/**
Regards, Peter
>
>>
>> On Mon, Jul 7, 2014 at 6:54 PM, Ivan Gerasimov
>> <ivan.gerasimov at oracle.com>
>> wrote:
>>
>>> Unfortunately, x + x << 1 causes the same overflow bug as 3*x:
>>>
>> x + (x << 1) is merely supposed to be possibly more efficient than 3*x.
>>
>>
>>> (int)(1431655766 + 1431655766 << 1) == 2
>>>
>> OK, I think my latest version doesn't have any overflow bugs.
>
More information about the core-libs-dev
mailing list