Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2019-09-05 16:24:58 +0000
committerThomas Watson2019-09-10 16:02:07 +0000
commitd2ee5fa2383547043bed51ebf81c2313cd939db5 (patch)
tree0284c010892340f623e764eaf3d383d6f2e9a914 /bundles/org.eclipse.osgi/container/src/org
parent63a9e1075ab029c5090a3d50cf52b82f052c62f6 (diff)
downloadrt.equinox.framework-d2ee5fa2383547043bed51ebf81c2313cd939db5.tar.gz
rt.equinox.framework-d2ee5fa2383547043bed51ebf81c2313cd939db5.tar.xz
rt.equinox.framework-d2ee5fa2383547043bed51ebf81c2313cd939db5.zip
Bug 550645 - Performance improvements to CaseInsensitiveDictionaryMap
Improve hashCode calculation to avoid Character.toUpper/LowerCase calls for ASCII chars and make hashCode final for CaseInsensitiveKey Improve put operations by not interning the key on every put. It is now up to the client to intern if necessary. Updated ManifestElement to do that for bundle manifest keys while parsing the bundle manifest. Also improved performance for keys that are not already present in the Map by avoiding a call to remove first. With these optimizations put together we should see ~4x perforamance improvement in the usage of the CaseInsensitiveDictionaryMap by the framework. Change-Id: Ibe21780b2be95cecab994fa2ca2e817d7bab112c Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
Diffstat (limited to 'bundles/org.eclipse.osgi/container/src/org')
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/CaseInsensitiveDictionaryMap.java51
1 files changed, 36 insertions, 15 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/CaseInsensitiveDictionaryMap.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/CaseInsensitiveDictionaryMap.java
index 73086a5d3..7f013b276 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/CaseInsensitiveDictionaryMap.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/CaseInsensitiveDictionaryMap.java
@@ -16,7 +16,16 @@ package org.eclipse.osgi.framework.util;
import static java.util.Objects.requireNonNull;
-import java.util.*;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
import org.eclipse.osgi.internal.messages.Msg;
import org.eclipse.osgi.util.NLS;
@@ -178,10 +187,14 @@ public class CaseInsensitiveDictionaryMap<K, V> extends Dictionary<K, V> impleme
public V put(K key, V value) {
requireNonNull(value);
if (key instanceof String) {
- Object wrappedKey = keyWrap(((String) key).intern());
- V previous = map.remove(wrappedKey); // remove so we put key into map
- map.put(wrappedKey, value);
- return previous;
+ Object wrappedKey = keyWrap(key);
+ V existing = map.put(wrappedKey, value);
+ if (existing != null) {
+ // must remove to replace key if case has changed
+ map.remove(wrappedKey);
+ map.put(wrappedKey, value);
+ }
+ return existing;
}
return map.put(requireNonNull(key), value);
}
@@ -388,25 +401,33 @@ public class CaseInsensitiveDictionaryMap<K, V> extends Dictionary<K, V> impleme
}
}
+ static int computeHashCode(String key) {
+ int h = 1;
+ for (char c : key.toCharArray()) {
+ if (c < 0x80) { // ASCII
+ if (c >= 'A' && c <= 'Z') {
+ c += 'a' - 'A'; // convert to ASCII lowercase
+ }
+ } else {
+ c = Character.toLowerCase(Character.toUpperCase(c));
+ }
+ h = 31 * h + c;
+ }
+ return h;
+ }
+
private static final class CaseInsensitiveKey {
final String key;
- private transient int hashCode;
+ final private int hashCode;
CaseInsensitiveKey(String key) {
this.key = key;
+ this.hashCode = computeHashCode(key);
}
@Override
public int hashCode() {
- int h = hashCode;
- if (h != 0) {
- return h;
- }
- h = 1;
- for (char c : key.toCharArray()) {
- h = 31 * h + Character.toLowerCase(Character.toUpperCase(c));
- }
- return hashCode = h;
+ return hashCode;
}
@Override

Back to the top