Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2019-09-10 13:34:24 +0000
committerThomas Watson2019-09-10 16:02:07 +0000
commitd610caa758aca82fa1e58801b3a36b9070f2d009 (patch)
tree85637e76311e847f9285134ec37117b795b2fd99
parentd2ee5fa2383547043bed51ebf81c2313cd939db5 (diff)
downloadrt.equinox.framework-d610caa758aca82fa1e58801b3a36b9070f2d009.tar.gz
rt.equinox.framework-d610caa758aca82fa1e58801b3a36b9070f2d009.tar.xz
rt.equinox.framework-d610caa758aca82fa1e58801b3a36b9070f2d009.zip
Bug 550645 - Cache common keys for CaseInsensitiveDictionaryMapI20190910-1800
Adds a static cache for common keys that uses a hardcoded switch statement for quick lookup of a common key during keyWrap. This reduces the penalty for non-common keys to be more manageable such that the performance benefit of the common key cache can be realized. Change-Id: I9a4ad5609cd0f07ebdc4a358b341a00232df17d4 Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/util/TestCaseinsensitiveMap.java24
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/CaseInsensitiveDictionaryMap.java150
2 files changed, 164 insertions, 10 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/util/TestCaseinsensitiveMap.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/util/TestCaseinsensitiveMap.java
index dd8730942..72891a41d 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/util/TestCaseinsensitiveMap.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/util/TestCaseinsensitiveMap.java
@@ -38,9 +38,11 @@ public class TestCaseinsensitiveMap extends CoreTest {
"jmx.objectname", //$NON-NLS-1$
// common bundle manifest headers
+ "Manifest-Version", // $NON-NLS-1$
Constants.BUNDLE_ACTIVATIONPOLICY, //
Constants.BUNDLE_ACTIVATOR, //
Constants.BUNDLE_CLASSPATH, //
+ Constants.BUNDLE_DESCRIPTION, //
Constants.BUNDLE_LICENSE, //
Constants.BUNDLE_LOCALIZATION, //
Constants.BUNDLE_MANIFESTVERSION, //
@@ -51,11 +53,13 @@ public class TestCaseinsensitiveMap extends CoreTest {
Constants.BUNDLE_SYMBOLICNAME, //
Constants.BUNDLE_VENDOR, //
Constants.BUNDLE_VERSION, //
+ Constants.DYNAMICIMPORT_PACKAGE, //
Constants.EXPORT_PACKAGE, //
Constants.FRAGMENT_HOST, //
Constants.IMPORT_PACKAGE, //
Constants.REQUIRE_BUNDLE, //
- Constants.REQUIRE_CAPABILITY //
+ Constants.REQUIRE_CAPABILITY, //
+ Constants.PROVIDE_CAPABILITY //
};
String[] OTHER_KEY_NAMES = new String[] {"test.key0", //
@@ -70,8 +74,8 @@ public class TestCaseinsensitiveMap extends CoreTest {
"test.key9" //
};
- private static final String VALUE1 = "test value1";
- private static final String VALUE2 = "test value2";
+ private static final String VALUE1 = "-VALUE1";
+ private static final String VALUE2 = "-VALUE2";
public void testCommonKeys() {
testKeys(COMMON_KEY_NAMES);
@@ -85,8 +89,8 @@ public class TestCaseinsensitiveMap extends CoreTest {
Map<String, Object> testMap = new CaseInsensitiveDictionaryMap<>();
// first put a value in for all common keys
for (String key : keys) {
- testMap.put(key, VALUE1);
- assertEquals("Wrong value found.", VALUE1, testMap.get(key));
+ testMap.put(key, key + VALUE1);
+ assertEquals("Wrong value found.", key + VALUE1, testMap.get(key));
}
Set<String> upperKeys = new HashSet<>();
@@ -94,16 +98,16 @@ public class TestCaseinsensitiveMap extends CoreTest {
// now upper case all keys
String upperKey = key.toUpperCase();
upperKeys.add(upperKey);
- assertEquals("Wrong value found.", VALUE1, testMap.get(upperKey));
+ assertEquals("Wrong value found.", key + VALUE1, testMap.get(upperKey));
// replace with value2 using upper case
- assertEquals("Wrong value found.", VALUE1, testMap.put(upperKey, VALUE2));
+ assertEquals("Wrong value found.", key + VALUE1, testMap.put(upperKey, key + VALUE2));
// both original key and upper case key should give same value
- assertEquals("Wrong value found.", VALUE2, testMap.get(key));
- assertEquals("Wrong value found.", VALUE2, testMap.get(upperKey));
+ assertEquals("Wrong value found.", key + VALUE2, testMap.get(key));
+ assertEquals("Wrong value found.", key + VALUE2, testMap.get(upperKey));
}
Set<String> currentKeys = testMap.keySet();
assertEquals("Wrong number of keys.", upperKeys.size(), currentKeys.size());
- assertTrue("Wrong keys found: " + currentKeys, upperKeys.containsAll(upperKeys));
+ assertTrue("Wrong keys found: " + currentKeys, upperKeys.containsAll(currentKeys));
}
}
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 7f013b276..6edaf1c67 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
@@ -28,6 +28,7 @@ import java.util.Objects;
import java.util.Set;
import org.eclipse.osgi.internal.messages.Msg;
import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.Constants;
/**
* CaseInsensitiveDictionaryMap classes. This class implements Dictionary and Map with
@@ -40,6 +41,151 @@ import org.eclipse.osgi.util.NLS;
* @since 3.13
*/
public class CaseInsensitiveDictionaryMap<K, V> extends Dictionary<K, V> implements Map<K, V> {
+ // common core service property keys
+ private static final CaseInsensitiveKey KEY_SERVICE_OBJECTCLASS = new CaseInsensitiveKey(Constants.OBJECTCLASS);
+ private static final CaseInsensitiveKey KEY_SERVICE_BUNDLE_ID = new CaseInsensitiveKey(Constants.SERVICE_BUNDLEID);
+ private static final CaseInsensitiveKey KEY_SERVICE_CHANGECOUNT = new CaseInsensitiveKey(Constants.SERVICE_CHANGECOUNT);
+ private static final CaseInsensitiveKey KEY_SERVICE_DESCRIPTION = new CaseInsensitiveKey(Constants.SERVICE_DESCRIPTION);
+ private static final CaseInsensitiveKey KEY_SERVICE_ID = new CaseInsensitiveKey(Constants.SERVICE_ID);
+ private static final CaseInsensitiveKey KEY_SERVICE_PID = new CaseInsensitiveKey(Constants.SERVICE_PID);
+ private static final CaseInsensitiveKey KEY_SERVICE_RANKING = new CaseInsensitiveKey(Constants.SERVICE_RANKING);
+ private static final CaseInsensitiveKey KEY_SERVICE_SCOPE = new CaseInsensitiveKey(Constants.SERVICE_SCOPE);
+ private static final CaseInsensitiveKey KEY_SERVICE_VENDER = new CaseInsensitiveKey(Constants.SERVICE_VENDOR);
+
+ // common SCR service property keys
+ private static final CaseInsensitiveKey KEY_COMPONENT_NAME = new CaseInsensitiveKey("component.name"); //$NON-NLS-1$
+ private static final CaseInsensitiveKey KEY_COMPONENT_ID = new CaseInsensitiveKey("component.id"); //$NON-NLS-1$
+
+ // common meta-type property keys
+ private static final CaseInsensitiveKey KEY_METATYPE_PID = new CaseInsensitiveKey("metatype.pid"); //$NON-NLS-1$
+ private static final CaseInsensitiveKey KEY_METATYPE_FACTORY_PID = new CaseInsensitiveKey("metatype.factory.pid"); //$NON-NLS-1$
+
+ // common event admin keys
+ private static final CaseInsensitiveKey KEY_EVENT_TOPICS = new CaseInsensitiveKey("event.topics"); //$NON-NLS-1$
+ private static final CaseInsensitiveKey KEY_EVENT_FILTER = new CaseInsensitiveKey("event.filter"); //$NON-NLS-1$
+
+ // jmx keys
+ private static final CaseInsensitiveKey KEY_JMX_OBJECTNAME = new CaseInsensitiveKey("jmx.objectname"); //$NON-NLS-1$
+
+ // common bundle manifest headers
+ private static final CaseInsensitiveKey KEY_JAR_MANIFESTVERSION = new CaseInsensitiveKey("Manifest-Version"); //$NON-NLS-1$
+ private static final CaseInsensitiveKey KEY_BUNDLE_ACTIVATIONPOLICY = new CaseInsensitiveKey(Constants.BUNDLE_ACTIVATIONPOLICY);
+ private static final CaseInsensitiveKey KEY_BUNDLE_ACTIVATOR = new CaseInsensitiveKey(Constants.BUNDLE_ACTIVATOR);
+ private static final CaseInsensitiveKey KEY_BUNDLE_CLASSPATH = new CaseInsensitiveKey(Constants.BUNDLE_CLASSPATH);
+ private static final CaseInsensitiveKey KEY_BUNDLE_DESCRIPTION = new CaseInsensitiveKey(Constants.BUNDLE_DESCRIPTION);
+ private static final CaseInsensitiveKey KEY_BUNDLE_LICENSE = new CaseInsensitiveKey(Constants.BUNDLE_LICENSE);
+ private static final CaseInsensitiveKey KEY_BUNDLE_LOCALIZATION = new CaseInsensitiveKey(Constants.BUNDLE_LOCALIZATION);
+ private static final CaseInsensitiveKey KEY_BUNDLE_MANIFESTVERSION = new CaseInsensitiveKey(Constants.BUNDLE_MANIFESTVERSION);
+ private static final CaseInsensitiveKey KEY_BUNDLE_NAME = new CaseInsensitiveKey(Constants.BUNDLE_NAME);
+ private static final CaseInsensitiveKey KEY_BUNDLE_NATIVECODE = new CaseInsensitiveKey(Constants.BUNDLE_NATIVECODE);
+ @SuppressWarnings("deprecation")
+ private static final CaseInsensitiveKey KEY_BUNDLE_REQUIREDEXECUTIONENVIRONMENT = new CaseInsensitiveKey(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
+ private static final CaseInsensitiveKey KEY_BUNDLE_SCM = new CaseInsensitiveKey(Constants.BUNDLE_SCM);
+ private static final CaseInsensitiveKey KEY_BUNDLE_SYMBOLICNAME = new CaseInsensitiveKey(Constants.BUNDLE_SYMBOLICNAME);
+ private static final CaseInsensitiveKey KEY_BUNDLE_VENDOR = new CaseInsensitiveKey(Constants.BUNDLE_VENDOR);
+ private static final CaseInsensitiveKey KEY_BUNDLE_VERSION = new CaseInsensitiveKey(Constants.BUNDLE_VERSION);
+ private static final CaseInsensitiveKey KEY_BUNDLE_DYNAMICIMPORT_PACKAGE = new CaseInsensitiveKey(Constants.DYNAMICIMPORT_PACKAGE);
+ private static final CaseInsensitiveKey KEY_BUNDLE_EXPORT_PACKAGE = new CaseInsensitiveKey(Constants.EXPORT_PACKAGE);
+ private static final CaseInsensitiveKey KEY_BUNDLE_FRAGMENT_HOST = new CaseInsensitiveKey(Constants.FRAGMENT_HOST);
+ private static final CaseInsensitiveKey KEY_BUNDLE_IMPORT_PACKAGE = new CaseInsensitiveKey(Constants.IMPORT_PACKAGE);
+ private static final CaseInsensitiveKey KEY_BUNDLE_REQUIRE_BUNDLE = new CaseInsensitiveKey(Constants.REQUIRE_BUNDLE);
+ private static final CaseInsensitiveKey KEY_BUNDLE_REQUIRE_CAPABILITY = new CaseInsensitiveKey(Constants.REQUIRE_CAPABILITY);
+ private static final CaseInsensitiveKey KEY_BUNDLE_PROVIDE_CAPABILITY = new CaseInsensitiveKey(Constants.PROVIDE_CAPABILITY);
+
+ @SuppressWarnings("deprecation")
+ public static CaseInsensitiveKey findCommonKeyIndex(String key) {
+ switch (key) {
+ // common core service property keys
+ case Constants.OBJECTCLASS :
+ return KEY_SERVICE_OBJECTCLASS;
+ case Constants.SERVICE_BUNDLEID :
+ return KEY_SERVICE_BUNDLE_ID;
+ case Constants.SERVICE_CHANGECOUNT :
+ return KEY_SERVICE_CHANGECOUNT;
+ case Constants.SERVICE_DESCRIPTION :
+ return KEY_SERVICE_DESCRIPTION;
+ case Constants.SERVICE_ID :
+ return KEY_SERVICE_ID;
+ case Constants.SERVICE_PID :
+ return KEY_SERVICE_PID;
+ case Constants.SERVICE_RANKING :
+ return KEY_SERVICE_RANKING;
+ case Constants.SERVICE_SCOPE :
+ return KEY_SERVICE_SCOPE;
+ case Constants.SERVICE_VENDOR :
+ return KEY_SERVICE_VENDER;
+
+ // common SCR service property keys
+ case "component.name" : //$NON-NLS-1$
+ return KEY_COMPONENT_NAME;
+ case "component.id" : //$NON-NLS-1$
+ return KEY_COMPONENT_ID;
+
+ // common meta-type property keys
+ case "metatype.pid" : //$NON-NLS-1$
+ return KEY_METATYPE_PID;
+ case "metatype.factory.pid" : //$NON-NLS-1$
+ return KEY_METATYPE_FACTORY_PID;
+
+ // common event admin keys
+ case "event.topics" : //$NON-NLS-1$
+ return KEY_EVENT_TOPICS;
+ case "event.filter" : //$NON-NLS-1$
+ return KEY_EVENT_FILTER;
+
+ // jmx keys
+ case "jmx.objectname" : //$NON-NLS-1$
+ return KEY_JMX_OBJECTNAME;
+
+ // common bundle manifest headers
+ case "Manifest-Version" : //$NON-NLS-1$
+ return KEY_JAR_MANIFESTVERSION;
+ case Constants.BUNDLE_ACTIVATIONPOLICY :
+ return KEY_BUNDLE_ACTIVATIONPOLICY;
+ case Constants.BUNDLE_ACTIVATOR :
+ return KEY_BUNDLE_ACTIVATOR;
+ case Constants.BUNDLE_CLASSPATH :
+ return KEY_BUNDLE_CLASSPATH;
+ case Constants.BUNDLE_DESCRIPTION :
+ return KEY_BUNDLE_DESCRIPTION;
+ case Constants.BUNDLE_LICENSE :
+ return KEY_BUNDLE_LICENSE;
+ case Constants.BUNDLE_LOCALIZATION :
+ return KEY_BUNDLE_LOCALIZATION;
+ case Constants.BUNDLE_MANIFESTVERSION :
+ return KEY_BUNDLE_MANIFESTVERSION;
+ case Constants.BUNDLE_NAME :
+ return KEY_BUNDLE_NAME;
+ case Constants.BUNDLE_NATIVECODE :
+ return KEY_BUNDLE_NATIVECODE;
+ case Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT :
+ return KEY_BUNDLE_REQUIREDEXECUTIONENVIRONMENT;
+ case Constants.BUNDLE_SCM :
+ return KEY_BUNDLE_SCM;
+ case Constants.BUNDLE_SYMBOLICNAME :
+ return KEY_BUNDLE_SYMBOLICNAME;
+ case Constants.BUNDLE_VENDOR :
+ return KEY_BUNDLE_VENDOR;
+ case Constants.BUNDLE_VERSION :
+ return KEY_BUNDLE_VERSION;
+ case Constants.DYNAMICIMPORT_PACKAGE :
+ return KEY_BUNDLE_DYNAMICIMPORT_PACKAGE;
+ case Constants.EXPORT_PACKAGE :
+ return KEY_BUNDLE_EXPORT_PACKAGE;
+ case Constants.FRAGMENT_HOST :
+ return KEY_BUNDLE_FRAGMENT_HOST;
+ case Constants.IMPORT_PACKAGE :
+ return KEY_BUNDLE_IMPORT_PACKAGE;
+ case Constants.REQUIRE_BUNDLE :
+ return KEY_BUNDLE_REQUIRE_BUNDLE;
+ case Constants.REQUIRE_CAPABILITY :
+ return KEY_BUNDLE_REQUIRE_CAPABILITY;
+ case Constants.PROVIDE_CAPABILITY :
+ return KEY_BUNDLE_PROVIDE_CAPABILITY;
+ }
+ return null;
+ }
+
final Map<Object, V> map;
/**
@@ -155,6 +301,10 @@ public class CaseInsensitiveDictionaryMap<K, V> extends Dictionary<K, V> impleme
*/
private Object keyWrap(Object key) {
if (key instanceof String) {
+ CaseInsensitiveKey commonKey = findCommonKeyIndex((String) key);
+ if (commonKey != null) {
+ return commonKey;
+ }
return new CaseInsensitiveKey((String) key);
}
return key;

Back to the top