RFR: [6904367]: (coll) IdentityHashMap is resized before exceeding the expected maximum size (original) (raw)

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

! 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;

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