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.");