Mercurial > hg > openjdk > jigsaw > jdk
changeset 7016:e57019d2f34a
8008167: IdentityHashMap.[keySet|values|entrySet].toArray speed-up
Reviewed-by: mduigou, martin
Contributed-by: Peter Levart <peter.levary@gmail.com>
author | mduigou |
---|---|
date | Wed, 13 Feb 2013 14:50:14 -0800 |
parents | 153884b550f0 |
children | 1405ad6afb1e |
files | src/share/classes/java/util/IdentityHashMap.java |
diffstat | 1 files changed, 85 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/util/IdentityHashMap.java Thu Feb 14 13:01:03 2013 +0000 +++ b/src/share/classes/java/util/IdentityHashMap.java Wed Feb 13 14:50:14 2013 -0800 @@ -25,6 +25,7 @@ package java.util; import java.io.*; +import java.lang.reflect.Array; /** * This class implements the <tt>Map</tt> interface with a hash table, using @@ -1010,6 +1011,37 @@ result += System.identityHashCode(key); return result; } + public Object[] toArray() { + return toArray(new Object[size()]); + } + @SuppressWarnings("unchecked") + public <T> T[] toArray(T[] a) { + int expectedModCount = modCount; + int size = size(); + if (a.length < size) + a = (T[]) Array.newInstance(a.getClass().getComponentType(), size); + Object[] tab = table; + int ti = 0; + for (int si = 0; si < tab.length; si += 2) { + Object key; + if ((key = tab[si]) != null) { // key present ? + // more elements than expected -> concurrent modification from other thread + if (ti >= size) { + throw new ConcurrentModificationException(); + } + a[ti++] = (T) unmaskNull(key); // unmask key + } + } + // fewer elements than expected or concurrent modification from other thread detected + if (ti < size || expectedModCount != modCount) { + throw new ConcurrentModificationException(); + } + // final null marker as per spec + if (ti < a.length) { + a[ti] = null; + } + return a; + } } /** @@ -1062,6 +1094,36 @@ public void clear() { IdentityHashMap.this.clear(); } + public Object[] toArray() { + return toArray(new Object[size()]); + } + @SuppressWarnings("unchecked") + public <T> T[] toArray(T[] a) { + int expectedModCount = modCount; + int size = size(); + if (a.length < size) + a = (T[]) Array.newInstance(a.getClass().getComponentType(), size); + Object[] tab = table; + int ti = 0; + for (int si = 0; si < tab.length; si += 2) { + if (tab[si++] != null) { // key present ? + // more elements than expected -> concurrent modification from other thread + if (ti >= size) { + throw new ConcurrentModificationException(); + } + a[ti++] = (T) tab[si]; // copy value + } + } + // fewer elements than expected or concurrent modification from other thread detected + if (ti < size || expectedModCount != modCount) { + throw new ConcurrentModificationException(); + } + // final null marker as per spec + if (ti < a.length) { + a[ti] = null; + } + return a; + } } /** @@ -1149,25 +1211,35 @@ } public Object[] toArray() { - int size = size(); - Object[] result = new Object[size]; - Iterator<Map.Entry<K,V>> it = iterator(); - for (int i = 0; i < size; i++) - result[i] = new AbstractMap.SimpleEntry<>(it.next()); - return result; + return toArray(new Object[size()]); } @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { + int expectedModCount = modCount; int size = size(); if (a.length < size) - a = (T[])java.lang.reflect.Array - .newInstance(a.getClass().getComponentType(), size); - Iterator<Map.Entry<K,V>> it = iterator(); - for (int i = 0; i < size; i++) - a[i] = (T) new AbstractMap.SimpleEntry<>(it.next()); - if (a.length > size) - a[size] = null; + a = (T[]) Array.newInstance(a.getClass().getComponentType(), size); + Object[] tab = table; + int ti = 0; + for (int si = 0; si < tab.length; si += 2) { + Object key; + if ((key = tab[si]) != null) { // key present ? + // more elements than expected -> concurrent modification from other thread + if (ti >= size) { + throw new ConcurrentModificationException(); + } + a[ti++] = (T) new AbstractMap.SimpleEntry(unmaskNull(key), tab[si + 1]); + } + } + // fewer elements than expected or concurrent modification from other thread detected + if (ti < size || expectedModCount != modCount) { + throw new ConcurrentModificationException(); + } + // final null marker as per spec + if (ti < a.length) { + a[ti] = null; + } return a; } }