Peter, seems you need to fix capacity():
int capacity = Integer.highestOneBit(expectedMaxSize + (expectedMaxSize << 1));
does not necessarily produces a negative number in the case of overflow.
Why don't you want to use the variant that from the latest Martin's webrev?
It seems to work correctly with your proposal too.
Sincerely yours,
Ivan
On 12.07.2014 22:12, Peter Levart wrote:
On 07/12/2014 05:47 PM, Peter Levart wrote:
If we're willing to pay the price of special-casing the
non-power-of-2 MAX_CAPACITY = (1 << 29) + (1 << 28), which amounts to
approx. 4% of performance,
Then here's a possible solution:
http://cr.openjdk.java.net/~plevart/jdk9-dev/IdentityHashMap/webrev.06/
Two fixes:
http://cr.openjdk.java.net/~plevart/jdk9-dev/IdentityHashMap/webrev.07/
One is a fix for possible overflow in resize() + rearrangement (which
is specific to my proposal) and the other is replacement of condition
that triggers resize in put() from (3*size > length) to (3*size >=
length). The later should be applied to Martin's latest version too, I
think, if it is decided that my proposal is inadequate.
Why is (3*size >= length) more appropriate condition to trigger
resize? Because it is more aligned with capacity(size) function which
is basically a clamped Integer.highestOneBit(3 * size).
Map preallocation makes a table with length = 2 *
capacity(expectedMaxSize)
(3 * size < 2 * highestOneBit(3*size)) is true for any size, so IHM
will never be resized if filled with size elements and table was
preallocated with length =
2 * highestOneBit(3*size) even if condition for resizing is changed
from (3*size > length) to (3*size >= length). Current condition
sometimes resizes a little to late when preallocation would already
create a bigger table.
Now if we change that, my proposed webrev.07 does not need
MAXIMUM_SIZE constant any more. Attempt to insert the 2^29-th element
(when size is about to become 2^29) triggers resize since at that time
length == 2 * MAXIMUM_CAPACITY which is exactly 3 * 2^29 and this
alone can be used as a trigger to throw OOME in resize()...
Regards, Peter