src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyHashMap.java

Print this page

        

@@ -102,11 +102,11 @@
  * immutable hash map, addition is constant time.  For LinkedHashMap it's O(N+C)
  * since we have to clone the older map.
  */
 public final class PropertyHashMap implements Map <String, Property> {
     /** Number of initial bins. Power of 2. */
-    private static final int INITIAL_BINS = 32;
+    private static final int INITIAL_BINS = 16;
 
     /** Threshold before using bins. */
     private static final int LIST_THRESHOLD = 8;
 
     /** Initial map. */

@@ -391,22 +391,52 @@
      * @param newSize New size of {@link PropertyHashMap}.
      *
      * @return Cloned {@link PropertyHashMap} with new size.
      */
     private PropertyHashMap cloneMap(final int newSize) {
-        Element[] newBins;
+        final Element[] newBins = cloneBins(newSize);
+        return new PropertyHashMap(newSize, newBins, list);
+    }
+
+    private Element[] cloneBins(final int newSize) {
         if (bins == null && newSize <= LIST_THRESHOLD) {
-            newBins = null;
+            return null;
         } else if (newSize > threshold) {
-            newBins = rehash(list, binsNeeded(newSize));
+            return rehash(list, binsNeeded(newSize));
         } else {
-            newBins = bins.clone();
+            return bins == null ? null : bins.clone();
         }
-        return new PropertyHashMap(newSize, newBins, list);
     }
 
+    /**
+     * Create a property map containing the given <code>properties</code>. The collection must not
+     * contain properties with duplicate keys or keys that represent valid array indices as this
+     * method does not perform any sanity checks.
+     *
+     * @param properties collection of properties
+     * @return the property hash map
+     */
+    public static PropertyHashMap create(final Collection<Property> properties) {
+        if (properties == null) {
+            return EMPTY_HASHMAP;
+        }
+
+        final int size = properties.size();
+        final Element[] bins = EMPTY_HASHMAP.cloneBins(size);
+        Element list = null;
 
+        for (final Property property : properties) {
+            final String key = property.getKey();
+            if (bins != null) {
+                final int binIndex = binIndex(bins, key);
+                final Element bin = bins[binIndex];
+                bins[binIndex] = new Element(bin, property);
+            }
+            list = new Element(list, property);
+        }
+        return new PropertyHashMap(size, bins, list);
+    }
 
     /**
      * Add a {@link Property} to a temporary {@link PropertyHashMap}, that has
      * been already cloned.  Removes duplicates if necessary.
      *

@@ -520,11 +550,10 @@
     @Override
     public boolean containsKey(final Object key) {
         if (key instanceof String) {
             return findElement((String)key) != null;
         }
-        assert key instanceof String;
         return false;
     }
 
     /**
      * Check if the map contains a key.

@@ -621,29 +650,22 @@
         private Element link;
 
         /** Element property. */
         private final Property property;
 
-        /** Element key. Kept separate for performance.) */
-        private final String key;
-
-        /** Element key hash code. */
-        private final int hashCode;
-
         /*
          * Constructors
          */
 
         Element(final Element link, final Property property) {
             this.link     = link;
             this.property = property;
-            this.key      = property.getKey();
-            this.hashCode = this.key.hashCode();
         }
 
         boolean match(final String otherKey, final int otherHashCode) {
-            return this.hashCode == otherHashCode && this.key.equals(otherKey);
+            final String key = property.getKey();
+            return key.hashCode() == otherHashCode && key.equals(otherKey);
         }
 
         /*
          * Entry implmentation.
          */

@@ -654,21 +676,21 @@
             return other instanceof Element && property.equals(((Element)other).property);
         }
 
         @Override
         public String getKey() {
-            return key;
+            return property.getKey();
         }
 
         @Override
         public Property getValue() {
             return property;
         }
 
         @Override
         public int hashCode() {
-            return hashCode;
+            return property.getKey().hashCode();
         }
 
         @Override
         public Property setValue(final Property value) {
             throw new UnsupportedOperationException("Immutable map.");