changeset 5721:114fbbeb8f75

7107613: scalability bloker in javax.crypto.CryptoPermissions Summary: Changed the type of field "perms" from Hashtable to ConcurrentHashMap. Reviewed-by: weijun, xuelei
author valeriep
date Fri, 10 Aug 2012 13:08:23 -0700
parents 629f357fc17b
children 175036ada2e3
files src/share/classes/javax/crypto/CryptoPermissions.java
diffstat 1 files changed, 52 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/javax/crypto/CryptoPermissions.java	Fri Aug 10 09:17:14 2012 -0400
+++ b/src/share/classes/javax/crypto/CryptoPermissions.java	Fri Aug 10 13:08:23 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,10 +30,16 @@
 import java.util.Hashtable;
 import java.util.Vector;
 import java.util.NoSuchElementException;
+import java.util.concurrent.ConcurrentHashMap;
 import java.io.Serializable;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.BufferedReader;
+import java.io.ObjectStreamField;
+import java.io.ObjectInputStream;
+import java.io.ObjectInputStream.GetField;
+import java.io.ObjectOutputStream;
+import java.io.ObjectOutputStream.PutField;
 import java.io.IOException;
 
 /**
@@ -61,15 +67,24 @@
 
     private static final long serialVersionUID = 4946547168093391015L;
 
-    // This class is similar to java.security.Permissions
-    private Hashtable<String, PermissionCollection> perms;
+    /**
+     * @serialField perms java.util.Hashtable
+     */
+    private static final ObjectStreamField[] serialPersistentFields = {
+        new ObjectStreamField("perms", Hashtable.class),
+    };
+
+    // Switched from Hashtable to ConcurrentHashMap to improve scalability.
+    // To maintain serialization compatibility, this field is made transient
+    // and custom readObject/writeObject methods are used.
+    private transient ConcurrentHashMap<String,PermissionCollection> perms;
 
     /**
      * Creates a new CryptoPermissions object containing
      * no CryptoPermissionCollections.
      */
     CryptoPermissions() {
-        perms = new Hashtable<String, PermissionCollection>(7);
+        perms = new ConcurrentHashMap<>(7);
     }
 
     /**
@@ -132,9 +147,7 @@
                         getPermissionCollection(cryptoPerm);
         pc.add(cryptoPerm);
         String alg = cryptoPerm.getAlgorithm();
-        if (!perms.containsKey(alg)) {
-            perms.put(alg, pc);
-        }
+        perms.putIfAbsent(alg, pc);
     }
 
     /**
@@ -377,18 +390,17 @@
     PermissionCollection getPermissionCollection(String alg) {
         // If this CryptoPermissions includes CryptoAllPermission,
         // we should return CryptoAllPermission.
-        if (perms.containsKey(CryptoAllPermission.ALG_NAME)) {
-            return perms.get(CryptoAllPermission.ALG_NAME);
-        }
+        PermissionCollection pc = perms.get(CryptoAllPermission.ALG_NAME);
+        if (pc == null) {
+            pc = perms.get(alg);
 
-        PermissionCollection pc = perms.get(alg);
-
-        // If there isn't a PermissionCollection for
-        // the given algorithm,we should return the
-        // PermissionCollection for the wildcard
-        // if there is one.
-        if (pc == null) {
-            pc = perms.get(CryptoPermission.ALG_NAME_WILDCARD);
+            // If there isn't a PermissionCollection for
+            // the given algorithm,we should return the
+            // PermissionCollection for the wildcard
+            // if there is one.
+            if (pc == null) {
+                pc = perms.get(CryptoPermission.ALG_NAME_WILDCARD);
+            }
         }
         return pc;
     }
@@ -414,6 +426,28 @@
         }
         return pc;
     }
+
+    private void readObject(ObjectInputStream s)
+        throws IOException, ClassNotFoundException {
+        ObjectInputStream.GetField fields = s.readFields();
+        @SuppressWarnings("unchecked")
+        Hashtable<String,PermissionCollection> permTable =
+                (Hashtable<String,PermissionCollection>)
+                (fields.get("perms", null));
+        if (permTable != null) {
+            perms = new ConcurrentHashMap<>(permTable);
+        } else {
+            perms = new ConcurrentHashMap<>();
+        }
+    }
+
+    private void writeObject(ObjectOutputStream s) throws IOException {
+        Hashtable<String,PermissionCollection> permTable =
+                new Hashtable<>(perms);
+        ObjectOutputStream.PutField fields = s.putFields();
+        fields.put("perms", permTable);
+        s.writeFields();
+    }
 }
 
 final class PermissionsEnumerator implements Enumeration<Permission> {
@@ -456,7 +490,6 @@
         } else {
             throw new NoSuchElementException("PermissionsEnumerator");
         }
-
     }
 
     private Enumeration<Permission> getNextEnumWithMore() {