summaryrefslogtreecommitdiffstats
path: root/luni/src/main/java/org
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2015-05-14 22:06:06 -0700
committerKenny Root <kroot@google.com>2015-05-19 08:49:35 -0700
commit8c75589cba8b490e9cbc479ce2129ccf480be8f3 (patch)
tree7e52f4f1f5fb3f74718131db6ef7afbedfb47d52 /luni/src/main/java/org
parent3f4bc323149f721cd91fc8b4c80e186a1dfe1ce7 (diff)
downloadlibcore-8c75589cba8b490e9cbc479ce2129ccf480be8f3.zip
libcore-8c75589cba8b490e9cbc479ce2129ccf480be8f3.tar.gz
libcore-8c75589cba8b490e9cbc479ce2129ccf480be8f3.tar.bz2
Get rid of old Harmony Services cache
Each java.security.Provider.Service has its own cache, so there is not a lot of benefit to having another cache of the caches. In fact, this makes adding a new provider a huge hit. This change makes adding a new empty provider go from ~5080 microseconds to 73 microseconds. (cherry picked from commit cc4791ad77128039c93d4c03b582d4dc397e6a02) Bug: 21159204 Change-Id: Ib23032f8cb0def79367a321b48241b6cc94de6b0
Diffstat (limited to 'luni/src/main/java/org')
-rw-r--r--luni/src/main/java/org/apache/harmony/security/fortress/Engine.java6
-rw-r--r--luni/src/main/java/org/apache/harmony/security/fortress/Services.java88
2 files changed, 31 insertions, 63 deletions
diff --git a/luni/src/main/java/org/apache/harmony/security/fortress/Engine.java b/luni/src/main/java/org/apache/harmony/security/fortress/Engine.java
index 855a8c7..1c794e5 100644
--- a/luni/src/main/java/org/apache/harmony/security/fortress/Engine.java
+++ b/luni/src/main/java/org/apache/harmony/security/fortress/Engine.java
@@ -152,7 +152,8 @@ public final class Engine {
}
/**
- * Returns a list of all possible matches for a given algorithm.
+ * Returns a list of all possible matches for a given algorithm. Returns
+ * {@code null} if no matches were found.
*/
public ArrayList<Provider.Service> getServices(String algorithm) {
int newCacheVersion = Services.getCacheVersion();
@@ -163,8 +164,7 @@ public final class Engine {
&& newCacheVersion == cacheEntry.cacheVersion) {
return cacheEntry.services;
}
- String name = this.serviceName + "." + algoUC;
- ArrayList<Provider.Service> services = Services.getServices(name);
+ ArrayList<Provider.Service> services = Services.getServices(serviceName, algoUC);
this.serviceCache = new ServiceCacheEntry(algoUC, newCacheVersion, services);
return services;
}
diff --git a/luni/src/main/java/org/apache/harmony/security/fortress/Services.java b/luni/src/main/java/org/apache/harmony/security/fortress/Services.java
index c81bf6b..5f3dfe0 100644
--- a/luni/src/main/java/org/apache/harmony/security/fortress/Services.java
+++ b/luni/src/main/java/org/apache/harmony/security/fortress/Services.java
@@ -29,16 +29,6 @@ import java.util.Locale;
* implementations for all "serviceName.algName".
*/
public class Services {
-
- /**
- * The HashMap that contains information about preferred implementations for
- * all serviceName.algName in the registered providers.
- * Set the initial size to 600 so we don't grow to 1024 by default because
- * initialization adds a few entries more than the growth threshold.
- */
- private static final HashMap<String, ArrayList<Provider.Service>> services
- = new HashMap<String, ArrayList<Provider.Service>>(600);
-
/**
* Save default SecureRandom service as well.
* Avoids similar provider/services iteration in SecureRandom constructor.
@@ -71,7 +61,6 @@ public class Services {
Provider p = (Provider) providerClass.newInstance();
providers.add(p);
providersNames.put(p.getName(), p);
- initServiceInfo(p);
return true;
} catch (ClassNotFoundException ignored) {
} catch (IllegalAccessException ignored) {
@@ -104,7 +93,7 @@ public class Services {
}
/**
- * Returns a copy of the registered providers as an array.
+ * Returns the actual registered providers.
*/
public static synchronized ArrayList<Provider> getProviders() {
return providers;
@@ -144,54 +133,39 @@ public class Services {
}
/**
- * Adds information about provider services into HashMap.
- */
- public static synchronized void initServiceInfo(Provider p) {
- for (Provider.Service service : p.getServices()) {
- String type = service.getType();
- if (cachedSecureRandomService == null && type.equals("SecureRandom")) {
- cachedSecureRandomService = service;
- }
- String key = type + "." + service.getAlgorithm().toUpperCase(Locale.US);
- appendServiceLocked(key, service);
- for (String alias : Engine.door.getAliases(service)) {
- key = type + "." + alias.toUpperCase(Locale.US);
- appendServiceLocked(key, service);
+ * Looks up the requested service by type and algorithm. The service
+ * {@code type} and should be provided in the same format used when
+ * registering a service with a provider, for example, "KeyFactory.RSA".
+ * Callers can cache the returned service information but such caches should
+ * be validated against the result of Service.getCacheVersion() before use.
+ * Returns {@code null} if there are no services found.
+ */
+ public static synchronized ArrayList<Provider.Service> getServices(String type,
+ String algorithm) {
+ ArrayList<Provider.Service> services = null;
+ for (Provider p : providers) {
+ Provider.Service s = p.getService(type, algorithm);
+ if (s != null) {
+ if (services == null) {
+ services = new ArrayList<>(providers.size());
+ }
+ services.add(s);
}
}
+ return services;
}
/**
- * Add or append the service to the key.
+ * Finds the first service offered of {@code type} and returns it.
*/
- private static void appendServiceLocked(String key, Provider.Service service) {
- ArrayList<Provider.Service> serviceList = services.get(key);
- if (serviceList == null) {
- serviceList = new ArrayList<Provider.Service>(1);
- services.put(key, serviceList);
+ private static synchronized Provider.Service getFirstServiceOfType(String type) {
+ for (Provider p : providers) {
+ Provider.Service s = Engine.door.getService(p, type);
+ if (s != null) {
+ return s;
+ }
}
- serviceList.add(service);
- }
-
- /**
- * Returns true if services does not contain any provider information.
- */
- public static synchronized boolean isEmpty() {
- return services.isEmpty();
- }
-
- /**
- * Looks up the requested service by type and algorithm. The
- * service key should be provided in the same format used when
- * registering a service with a provider, for example,
- * "KeyFactory.RSA".
- *
- * Callers can cache the returned service information but such
- * caches should be validated against the result of
- * Service.getCacheVersion() before use.
- */
- public static synchronized ArrayList<Provider.Service> getServices(String key) {
- return services.get(key);
+ return null;
}
/**
@@ -219,13 +193,7 @@ public class Services {
public static synchronized int getCacheVersion() {
if (needRefresh) {
cacheVersion++;
- synchronized (services) {
- services.clear();
- }
- cachedSecureRandomService = null;
- for (Provider p : providers) {
- initServiceInfo(p);
- }
+ cachedSecureRandomService = getFirstServiceOfType("SecureRandom");
needRefresh = false;
}
return cacheVersion;