diff options
author | Kenny Root <kroot@google.com> | 2015-05-14 22:06:06 -0700 |
---|---|---|
committer | Kenny Root <kroot@google.com> | 2015-05-19 08:49:35 -0700 |
commit | 8c75589cba8b490e9cbc479ce2129ccf480be8f3 (patch) | |
tree | 7e52f4f1f5fb3f74718131db6ef7afbedfb47d52 /luni/src/main/java/org | |
parent | 3f4bc323149f721cd91fc8b4c80e186a1dfe1ce7 (diff) | |
download | libcore-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.java | 6 | ||||
-rw-r--r-- | luni/src/main/java/org/apache/harmony/security/fortress/Services.java | 88 |
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; |